package com.lanchetech.user.service.impl;


import com.alibaba.excel.util.CollectionUtils;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.lanchetech.bean.request.*;
import com.lanchetech.bean.response.*;
import com.lanchetech.bean.util.PageHelpUtil;
import com.lanchetech.bean.vo.*;
import com.lanchetech.common.enums.*;
import com.lanchetech.common.exception.ResultCodeException;
import com.lanchetech.common.util.EmojiFilter;
import com.lanchetech.common.util.SensitiveInfoUtil;
import com.lanchetech.dao.*;
import com.lanchetech.entity.*;
import com.lanchetech.service.*;
import com.lanchetech.user.config.JwtTokenUtil;
import com.lanchetech.user.service.*;
import jdk.net.SocketFlow;
import org.hashids.Hashids;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Calendar;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.lanchetech.common.constants.JypConstant.*;
import static com.lanchetech.common.enums.AllIdentityTypeEnum.*;

@Service

public class UserServiceImpl implements UserService {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    UserMapper userMapper;

    @Autowired
    ArticleMapper articleMapper;

    @Autowired
    UserRelationshipMapper userRelationshipMapper;

    @Autowired
    SmsService smsService;

    @Autowired
    UserAddressMapper userAddressMapper;

    @Autowired
    UserInfoMapper userInfoMapper;

    @Autowired
    WithdrawMapper withdrawMapper;

    @Autowired
    MiniappService miniappService;

    @Autowired
    AreaMapper areaMapper;

    @Autowired
    OrdersMapper ordersMapper;


    @Value("${domain.url}")
    private String domainUrl;

    @Autowired
    CommonService commonService;

    @Autowired
    TracksMapper tracksMapper;

    @Autowired
    UserCollectionMapper userCollectionMapper;

    @Value("${customer.hashid.couponsalt}")
    private String salt;

    @Autowired
    InviteCodeService inviteCodeService;

    @Autowired
    SearchHistoryMapper searchHistoryMapper;

    @Autowired
    AfterSaleMapper afterSaleMapper;

    @Autowired
    SpuMapper spuMapper;

    @Autowired
    DaoService daoService;

    @Autowired
    PrivilegeMapper privilegeMapper;

    @Autowired
    UserCommissionMapper userCommissionMapper;

    @Autowired
    UserCouponMapper userCouponMapper;

    @Autowired
    CouponMapper couponMapper;

    @Autowired
    MarketingServiceImpl marketingService;

    @Autowired
    ConsumptionAmountMapper consumptionAmountMapper;

    @Autowired
    DiseaseReportMapper diseaseReportMapper;

    @Autowired
    BusinessCardMapper businessCardMapper;

    @Autowired
    GroupService groupService;

    @Autowired
    UserGroupMapper userGroupMapper;

    @Autowired
    CardFlowMapper cardFlowMapper;

    @Autowired
    IdentityMapper identityMapper;

    @Autowired
    HipoConfigMapper hipoConfigMapper;

    @Autowired
    InformationMapper informationMapper;

    @Autowired
    ShopApplyMapper shopApplyMapper;

    @Autowired
    CoinFlowMapper coinFlowMapper;

    @Autowired
    RewardQueueMapper rewardQueueMapper;

    @Autowired
    BalanceFlowMapper balanceFlowMapper;

    @Autowired
    CatalogMapper catalogMapper;

    @Autowired
    LogisticsService logisticsService;

    @Autowired
    LogisticsCompanyMapper logisticsCompanyMapper;

    @Autowired
    OrderAddressMapper orderAddressMapper;

    @Autowired
    OrderSkuMapper orderSkuMapper;

    @Autowired
    AgentCommissionMapper agentCommissionMapper;

    @Autowired
    UserRoleMapper userRoleMapper;

    @Autowired
    UserAgentLevelMapper userAgentLevelMapper;

    @Autowired
    UserVoucherMapper userVoucherMapper;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    ShopCollectionMapper shopCollectionMapper;

    @Autowired
    SecondRelationshipMapper secondRelationshipMapper;

    @Autowired
    MsgUserMapper msgUserMapper;

    @Autowired
    JwtTokenUtil jwtTokenUtil;


    @Autowired
    ShopRelationshipMapper shopRelationshipMapper;

    @Autowired
    AudioListenMapper audioListenMapper;

    @Autowired
    BaiduService baiduService;

    @Autowired
    CommonFarmService commonFarmService;

    @Autowired
    VoiceSetMapper voiceSetMapper;

    @Autowired
    ShopMapper shopMapper;

    @Autowired
    RankRecordMapper rankRecordMapper;

    @Autowired
    BossMapper bossMapper;

    @Autowired
    TenantMapper tenantMapper;

    @Autowired
    AreaApplyDetailMapper areaApplyDetailMapper;

    @Autowired
    AreaApplyMapper areaApplyMapper;

    @Autowired
    SuggestionMapper suggestionMapper;

    @Autowired
    AreaPartnerMapper areaPartnerMapper;

    @Autowired
    CurrentIdentityMapper currentIdentityMapper;

    @Autowired
    MsgMapper msgMapper;

    @Value("${im.jwt.secret}")
    public String secret;

    @Autowired
    BonusCountMapper bonusCountMapper;

    @Autowired
    BossRelationshipMapper bossRelationshipMapper;

    @Autowired
    BossIdentityMapper bossIdentityMapper;

    @Autowired
    InviteFirstBuyMapper inviteFirstBuyMapper;

    @Autowired
    PerformanceAmountMapper performanceAmountMapper;

    @Autowired
    GiveIdentityRecordMapper giveIdentityRecordMapper;

    @Autowired
    SubscribeRecordMapper subscribeRecordMapper;

    @Autowired
    QuartzService quartzService;

    @Autowired
    FlashSaleActivityMapper flashSaleActivityMapper;

    @Autowired
    FlashSaleSpuMapper flashSaleSpuMapper;

    @Autowired
    private Scheduler scheduler;

    @Autowired
    ReportMapper reportMapper;

    @Autowired
    DividendPrecipitationMapper dividendPrecipitationMapper;

    @Autowired
    GroupsPerformanceMapper groupsPerformanceMapper;

    @Autowired
    ShareholderPerformanceMapper shareholderPerformanceMapper;

    @Autowired
    WelfareFlowMapper welfareFlowMapper;

    @Autowired
    LevelService levelService;

    @Autowired
    CommissionService commissionService;

    @Autowired
    TenantFlowMapper tenantFlowMapper;

    @Autowired
    TicketMapper ticketMapper;
    @Autowired
    private ShopService shopService;
    @Autowired
    private UserCelebrityMapper userCelebrityMapper;


    @Autowired
    private LotteryOpportunityMapper lotteryOpportunityMapper;

    private Long getUserShopId(User user) {
        return user.getShopId();
    }


    @Override
    public ResultData<UserDetailResp> getUserDetail(User user) {
        UserDetailResp userDetailResp = new UserDetailResp();
        BeanUtils.copyProperties(user, userDetailResp);
        userDetailResp.setInviteCode(inviteCodeService.generateInviteCode(user.getId()));


        MsgUser msgUser = msgUserMapper.findOneByRelateIdAndRole(user.getId(), MsgUserRoleEnum.USER.getRole());
        userDetailResp.setChatToken(jwtTokenUtil.generateToken(msgUser, secret));
        userDetailResp.setMsgUserId(msgUser.getId());
        CurrentIdentity currentIdentity = currentIdentityMapper.findOneByUserId(user.getId());
        if (currentIdentity != null) {
            userDetailResp.setCurrentIdentity(currentIdentity.getAllIdentityType());
        }
        userDetailResp.setIdentity(identityMapper.findOneByUserId(user.getId()));
        userDetailResp.setIsBoss(bossIdentityMapper.findOneByUserId(user.getId()) != null);

        //判断用户是否有抽奖机会
        Integer count = lotteryOpportunityMapper.getLotteryOpportunity(user.getId());
        log.info("用户抽奖机会,userId:{},count:{}",user.getId(),count);
        userDetailResp.setWhetherLottery(0);
        if (null != count && count >= 1){
            userDetailResp.setWhetherLottery(1);
        }

        return new ResultData<>(userDetailResp);
    }

    @Override
    public ResultData<UserInfo> getUserInfo(User user) {
        return new ResultData<>(userInfoMapper.findOneByUserId(user.getId()));
    }

    @Override
    public BaseResp bindInviteCode(Long subordinateUserId, String inviteCode, String username) {
        // 只允许注册时绑定关系，其他情况不允许绑定关系。避免出现a是b的上级，b是c的上级c是a的上级，b间接成为了a的上上级，二级返佣会有影响。

        Long id = inviteCodeService.decodeInviteCode(inviteCode);
        User superior = userMapper.selectByPrimaryKey(id);

        // 邀请码错误或邀请者用户不存在
        if (superior == null) {
            return new BaseResp(ResultCode.INVITE_CODE_ERROR);
        }

        // 一个用户不能自己邀请自己
        if (subordinateUserId.equals(id)) {
            return new BaseResp(ResultCode.CAN_NOT_INVITE_YOURSELF);
        }

        // 一个用户只能有一个上级，一个用户可以有无数下级
        // 下级不能已经绑定过
        UserRelationship one = userRelationshipMapper.findOneBySubordinateId(subordinateUserId);

        // 下级不能已经是对方的上级
        UserRelationship two = userRelationshipMapper.findOneBySuperiorIdAndSubordinateId(subordinateUserId, superior.getId());
        if (one == null && two == null) {
            UserRelationship userRelationship = new UserRelationship();
            userRelationship.setSuperiorId(superior.getId());
            userRelationship.setSubordinateId(subordinateUserId);
            userRelationship.setCreatedAt(new Date());
            userRelationship.setUpdatedAt(new Date());
            userRelationship.setStatus(RelationshipStatusEnum.NOT_BIND.getStatus());

            Identity identity = identityMapper.findOneByUserId(superior.getId());

            userRelationship.setType(identity == null ? (byte) -1 : identity.getType());
            userRelationship.setSubordinateLevel(UserLevelEnum.CUSTOMER.getLevel());
            userRelationshipMapper.insert(userRelationship);

            // 创建二级绑定关系
            secondRelationshipMapper.insert(SecondRelationship.builder().superiorId(superior.getId()).subordinateId(subordinateUserId).createdAt(new Date()).build());

            // 农场任务
            commonFarmService.checkTaskDone(superior, FarmTaskKindEnum.INVITE.getKind(), null, null);

            //校验并更新新人邀请数量
            checkAndUpdateInvoiceCount(username, subordinateUserId, superior);

            return new BaseResp();
        } else {
            return new BaseResp(ResultCode.DO_NOT_BIND_AGAIN);
        }
    }


    void checkAndUpdateInvoiceCount(String username, Long subordinateUserId, User superior) {
        //是否重复注册
        Long usernameLikeCount = userMapper.countByUsernameLike(username);
        if (usernameLikeCount != null && usernameLikeCount == 1) {
            //上级是否重复注册
            Long superiorLikeCount = userMapper.countByUsernameLike(superior.getUsername());
            if (superiorLikeCount != null && superiorLikeCount == 1) {
                Identity superiorIdentity = identityMapper.findOneByUserId(superior.getId());
                if (superiorIdentity != null) {
                    //推荐奖励配置
                    Map<String, String> hipoConfigMap = daoService.getHipoConfigMap();
                    Integer inviteL2Count = Integer.valueOf(hipoConfigMap.get(HipoConfigEnum.INVITE_L2_COUNT.getConfig()));
                    BigDecimal inviteL2Reward = new BigDecimal(hipoConfigMap.get(HipoConfigEnum.INVITE_L2_REWARD.getConfig()));
                    Integer inviteL1Count = Integer.valueOf(hipoConfigMap.get(HipoConfigEnum.INVITE_L1_COUNT.getConfig()));
                    BigDecimal inviteL1Reward = new BigDecimal(hipoConfigMap.get(HipoConfigEnum.INVITE_L1_REWARD.getConfig()));

                    if (superiorIdentity.getInviteCount() + 1 >= inviteL2Count) {
                        if (superiorIdentity.getInviteRewardLevel() <= 1) {
                            identityMapper.updateInviteCountAndInviteRewardLevelAndUpdateAtById(superiorIdentity.getInviteCount() + 1, 2, new Date(), superiorIdentity.getId());
                            updateCardFlow(superior, inviteL2Reward, subordinateUserId, "推荐新人等级2奖励");
                        }
                    } else if (superiorIdentity.getInviteCount() + 1 >= inviteL1Count) {
                        if (superiorIdentity.getInviteRewardLevel() == 0) {
                            identityMapper.updateInviteCountAndInviteRewardLevelAndUpdateAtById(superiorIdentity.getInviteCount() + 1, 1, new Date(), superiorIdentity.getId());
                            updateCardFlow(superior, inviteL1Reward, subordinateUserId, "推荐新人等级1奖励");
                        }
                    } else {
                        identityMapper.updateInviteCountAndInviteRewardLevelAndUpdateAtById(superiorIdentity.getInviteCount() + 1, superiorIdentity.getInviteRewardLevel(), new Date(), superiorIdentity.getId());
                    }
                }
            }
        }
    }

    private void updateCardFlow(User superior, BigDecimal amount, Long subordinateUserId, String remark) {
        BigDecimal cardPoint = superior.getCardPoint().add(amount);
        userMapper.updateCardPointById(cardPoint, superior.getId());
        cardFlowMapper.insert(CardFlow.builder().userId(superior.getId()).amount(amount).tradeType(CardTradeTypeEnum.INVITE_REWARD.getTradeType()).type(CardTradeTypeEnum.INVITE_REWARD.getType()).cardPoint(cardPoint).relateId(subordinateUserId).remark(remark).createdAt(new Date()).build());
    }


    @Override
    public BaseResp updatePhone(User user, String phone, String code) {
        // 验证码是否正确
        if (!smsService.verifySms(phone, code)) {
            return new BaseResp(ResultCode.SMS_CODE_WRONG);
        }

        // 判断手机号是否已经存在
        User result = userMapper.findOneByUsername(phone);
        if (result != null) {
            return new BaseResp(ResultCode.PHONE_EXISTS);
        }

        userMapper.updateUsernameById(phone, user.getId());
        return new BaseResp();
    }

    @Override
    public BaseResp updateNickname(User user, String nickname) {
        user.setNickname(EmojiFilter.filterEmoji(nickname));
        userMapper.updateNicknameById(nickname, user.getId());
        return new BaseResp();
    }

    @Override
    public BaseResp rebindWechat(User user, RegisterReq req) {
        User updateUser = new User();
        // 获取openid 并查看此openid用户是否已存在
        String openid = miniappService.getUserOpenid(req.getJscode());
        if (openid == null) {
            return new BaseResp(ResultCode.GET_OPENID_FAIL);
        }
        User result = userMapper.findOneByOpenid(openid);
        if (result != null) {
            return new BaseResp(ResultCode.OPENID_EXISTS);
        }

        // 更新微信
        updateUser.setId(user.getId());
        updateUser.setOpenid(openid);
        updateUser.setNickname(EmojiFilter.filterEmoji(req.getNickname()));
        updateUser.setAvatar(req.getAvatar());
        updateUser.setUpdatedAt(new Date());
        userMapper.updateByPrimaryKeySelective(updateUser);

        return new BaseResp();
    }

    @Override
    public ResultData<List<UserAddress>> getUserAddressList(User user) {
        List<UserAddress> list = userAddressMapper.findAllByUserId(user.getId());
        if (!CollectionUtils.isEmpty(list)) {
            for (UserAddress userAddress : list) {
                userAddress.setPhone(SensitiveInfoUtil.mobilePhone(userAddress.getPhone()));
            }
        }
        return new ResultData<>(list);
    }

    @Override
    public BaseResp updateAvatar(User user, String avatar) {
        userMapper.updateAvatarById(avatar, user.getId());

        // 同时修改此用户的聊天用户头像
        MsgUser msgUser = msgUserMapper.findOneByRelateIdAndRole(user.getId(), MsgUserRoleEnum.USER.getRole());
        if (msgUser != null) {
            msgUser.setAvatar(avatar);
            msgUserMapper.updateByPrimaryKeySelective(msgUser);
        }
        return new BaseResp();
    }

    @Override
    public ResultData<UserAddress> getUserAddress(User user, Long id) {
        return new ResultData<>(userAddressMapper.findOneByIdAndUserId(id, user.getId()));
    }

    @Override
    public BaseResp editUserAddress(User user, UserAddress userAddress) {
        // 兼容获取微信地址时，无省、市code
        if (userAddress.getCity() == null || userAddress.getProvince() == null) {
            Area area = areaMapper.selectByPrimaryKey(userAddress.getArea());
            if (area != null && AreaLevelEnum.AREA.getLevel().equals(area.getLevelType())) {
                Area city = areaMapper.selectByPrimaryKey(area.getParentId());
                userAddress.setCity(city.getId());
                userAddress.setProvince(city.getParentId());
                userAddress.setMergerName(area.getMergerName().substring(3) + ",");
            } else {
                return new BaseResp(ResultCode.AREA_ERROR);
            }
        }

        if (userAddress.getId() == null) {
            // 创建
            // 每人只能创建最多20个地址
            Long count = userAddressMapper.countByUserId(user.getId());
            if (count >= 20) {
                return new BaseResp(ResultCode.ADDRESS_MORE_THAN_LIMIT);
            }
            if (ToggleEnum.ON.getStatus().equals(userAddress.getMain())) {
                // 如果是主地址，则要清空之前的主地址
                userAddressMapper.resetMain(user.getId());
            }
            userAddress.setUserId(user.getId());
            userAddress.setCreatedAt(new Date());
            userAddress.setUpdatedAt(new Date());
            userAddressMapper.insert(userAddress);
        } else {
            // 编辑
            // 防止被他人修改
            UserAddress result = userAddressMapper.findOneByIdAndUserId(userAddress.getId(), user.getId());
            if (result == null) {
                return new BaseResp(ResultCode.FAIL);
            } else {
                if (ToggleEnum.ON.getStatus().equals(userAddress.getMain())) {
                    // 如果是主地址，则要清空之前的主地址
                    userAddressMapper.resetMain(user.getId());
                }
                userAddress.setUpdatedAt(new Date());
                userAddressMapper.updateByPrimaryKeySelective(userAddress);
            }
        }
        return new BaseResp();
    }

    @Override
    public BaseResp deleteUserAddress(User user, Long id) {
        userAddressMapper.deleteByIdAndUserId(id, user.getId());
        return new BaseResp();
    }

    @Override
    public ResultData<UserAddress> getMainUserAddress(User user) {
        if (user == null) {
            return new ResultData<>(null);
        }
        UserAddress userAddress = userAddressMapper.findOneMainUserAddress(user.getId());
        if (userAddress != null) {
            userAddress.setPhone(SensitiveInfoUtil.mobilePhone(userAddress.getPhone()));
        }
        return new ResultData<>(userAddress);
    }

    @Override
    public ResultData<BasePageResp<RelationshipResp>> getUserSubordinatePage(User user, RelationshipReq req) {
        req.setSuperiorId(user.getId());

        if (!StringUtils.isEmpty(req.getNickname())) {
            User result = userMapper.findOneByNicknameLike(req.getNickname());
            req.setSubordinateId(result == null ? 0L : result.getId());
        }

        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<RelationshipResp> list = userRelationshipMapper.findAllPageLeftIdentity(req);

        if (CollectionUtils.isEmpty(list)) {
            return PageHelpUtil.buildPage(list, page);
        }
        Map<Long, User> userMap = daoService.getUserMap(list.stream().map(RelationshipResp::getSubordinateId).collect(Collectors.toList()));
        Map<Long, FarmUser> farmUserMap = daoService.getFarmUserMap(list.stream().map(RelationshipResp::getSubordinateId).collect(Collectors.toList()));
        list.stream().forEach(item -> {
            item.setIsFarmUser(farmUserMap.containsKey(item.getSubordinateId()));
            item.setSubordinateNickname(userMap.get(item.getSubordinateId()).getNickname());
            item.setSubordinatePhone(userMap.get(item.getSubordinateId()).getUsername());
            item.setSubordinateAvatar(userMap.get(item.getSubordinateId()).getAvatar());
            item.setSubordinateLevel(userMap.get(item.getSubordinateId()).getLevel());
        });

        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public BaseResp changeUserRelationship(User user, String inviteCode) {
        UserRelationship userRelationship = userRelationshipMapper.findOneBySubordinateId(user.getId());
        Long superiorId = inviteCodeService.decodeInviteCode(inviteCode);

        if (superiorId == null) {
            return new BaseResp();
        }

        if (user.getId().equals(superiorId)) {
            return new BaseResp();
        }

        Identity identity = identityMapper.findOneByUserId(superiorId);

        if (userRelationship == null) {
            userRelationshipMapper.insert(UserRelationship.builder().superiorId(superiorId).subordinateId(user.getId()).createdAt(new Date()).updatedAt(new Date()).status(RelationshipStatusEnum.NOT_BIND.getStatus()).type(identity == null ? (byte) -1 : identity.getType()).subordinateLevel(user.getLevel()).build());
        } else {
            if (RelationshipStatusEnum.NOT_BIND.getStatus().equals(userRelationship.getStatus()) && !userRelationship.getSuperiorId().equals(superiorId)) {
                userRelationship.setSuperiorId(superiorId);
                userRelationship.setUpdatedAt(new Date());
                userRelationship.setType(identity == null ? (byte) -1 : identity.getType());
                userRelationship.setSubordinateLevel(user.getLevel());
                userRelationshipMapper.updateByPrimaryKeySelective(userRelationship);
            }
        }

        SecondRelationship secondRelationship = secondRelationshipMapper.findOneBySubordinateId(user.getId());
        if (secondRelationship == null) {
            // 创建二级绑定关系
            secondRelationshipMapper.insert(SecondRelationship.builder().superiorId(superiorId).subordinateId(user.getId()).createdAt(new Date()).build());
        } else {
            secondRelationship.setSuperiorId(superiorId);
            secondRelationship.setCreatedAt(new Date());
            secondRelationshipMapper.updateByPrimaryKeySelective(secondRelationship);
        }

        return new BaseResp();
    }

    @Override
    public BaseResp updateUserIdCardAndRealName(User user, UserInfo userInfo) {
        userInfo.setUserId(user.getId());
        userInfo.setUpdatedAt(new Date());
        userInfoMapper.updateIdCardAndRealNameAndUpdatedAtByUserId(userInfo);
        return new BaseResp();
    }

    @Override
    public ResultData<String> getInviteQrcode(User user) {
        ResultData<String> resultData = new ResultData<>();
        try {
            String url = domainUrl + "/invite?type=share&inviteCode=" + inviteCodeService.generateInviteCode(user.getId());
            String image = commonService.createQrcode(url, 100, 100);
            resultData.setValue(image);
            return resultData;
        } catch (IOException e) {
            resultData.setResultCode(ResultCode.FAIL);
            log.error(e.toString());
            return resultData;
        }
    }

    @Override
    public ResultData<String> getBossInviteQrcode(User user) {
        ResultData<String> resultData = new ResultData<>();
        try {
            String url = domainUrl + "/bossInvite?type=bossInvite&inviteCode=" + inviteCodeService.generateInviteCode(user.getId());
            String image = commonService.createQrcode(url, 100, 100);
            resultData.setValue(image);
            return resultData;
        } catch (IOException e) {
            resultData.setResultCode(ResultCode.FAIL);
            log.error(e.toString());
            return resultData;
        }
    }


    @Override
    public ResultData<String> getExpertInviteQrcode(User user) {
        ResultData<String> resultData = new ResultData<>();
        try {
            String url = domainUrl + "/expertInvite?type=expertInvite&inviteCode=" + inviteCodeService.generateInviteCode(user.getId());
            String image = commonService.createQrcode(url, 100, 100);
            resultData.setValue(image);
            return resultData;
        } catch (IOException e) {
            resultData.setResultCode(ResultCode.FAIL);
            log.error(e.toString());
            return resultData;
        }
    }

    @Override
    public ResultData<MineDetailVO> getMineStatistics(User user) {

        MineDetailVO mineDetailVO = new MineDetailVO();
        // 待付款/待收货/待评价
        MineStatisticsVO mineStatisticsVO = ordersMapper.countOrdersByOrderType(user.getId(), OrderTypeEnum.ONLINE_EXPRESS.getType());

        MineStatisticsVO shopStatisticsVO = ordersMapper.countOrdersByOrderType(user.getId(), OrderTypeEnum.ONLINE_SELF.getType());
        // 商品收藏
        mineStatisticsVO.setCollection(userCollectionMapper.countByUserId(user.getId()));
        // 我的足迹
        mineStatisticsVO.setTracks(tracksMapper.countByUserId(user.getId()));
        // 待售后
        mineStatisticsVO.setAfterSale(afterSaleMapper.countByUserIdAndStatusAndOrderType(user.getId(), OrderTypeEnum.ONLINE_EXPRESS.getType()));

        // 商店订单的统计
        mineStatisticsVO.setShopPaid(shopStatisticsVO.getPaid());
        mineStatisticsVO.setShopComment(shopStatisticsVO.getComment());
        mineStatisticsVO.setShopUnpay(shopStatisticsVO.getUnpay());
        mineStatisticsVO.setShopAfterSale(afterSaleMapper.countByUserIdAndStatusAndOrderType(user.getId(), OrderTypeEnum.ONLINE_SELF.getType()));

        BigDecimal freeze = userCommissionMapper.sumFreeze(user.getId(), UserCommissionStatusEnum.FREEZE.getStatus(), BusinessTypeEnum.USER.getType());

        mineStatisticsVO.setPoint(user.getPoint());


        mineStatisticsVO.setVoucherCount(userVoucherMapper.countByUserIdAndStatus(user.getId(), VoucherStatusEnum.AVAILABLE.getStatus()));


        BigDecimal userAmount = withdrawMapper.sumByUserIdAndStatusAndBusinessType(user.getId(), WithdrawStatusEnum.SUCCESS.getStatus(), BusinessTypeEnum.USER.getType());
        BigDecimal userIssue = userCommissionMapper.sumByUserIdAndBusinessTypeAndStatus(user.getId(), BusinessTypeEnum.USER.getType(), UserCommissionStatusEnum.ISSUED.getStatus());

        mineStatisticsVO.setShopPoint(BigDecimal.ZERO);
        if (user.getShopId() != null) {
            Boss boss = bossMapper.findOneByShopId(user.getShopId());
            if (boss != null && boss.getUserId().equals(user.getId())) {
                Tenant tenant = tenantMapper.selectByPrimaryKey(user.getShopId());
                mineStatisticsVO.setShopPoint(tenant.getPoint());
            }
        }

        if (userAmount == null) {
            userAmount = BigDecimal.ZERO;
        }
        if (userIssue == null) {
            userIssue = BigDecimal.ZERO;
        }

        if (freeze != null) {
            mineStatisticsVO.setUserPoint(user.getPoint().add(freeze));
            mineStatisticsVO.setUserFreezeAmount(freeze);
        } else {
            mineStatisticsVO.setUserPoint(user.getPoint());
            mineStatisticsVO.setUserFreezeAmount(BigDecimal.ZERO);
        }


        // 获取物流信息
        Orders orders = ordersMapper.findTopOneByUserIdAndStatus(user.getId());
        if (orders != null) {
            List<OrderSkuVO> orderSkuVOS = orderSkuMapper.findAllByOrderId(orders.getId());
            mineDetailVO.setProductImage(spuMapper.selectByPrimaryKey(orderSkuVOS.get(0).getSpuId()).getMainImage());
            if (orders.getLogisticsCompany() != null) {
                mineDetailVO.setLogisticsCompany(logisticsCompanyMapper.findOneByCode(orders.getLogisticsCompany()).getName());
                OrderAddress orderAddress = orderAddressMapper.findOneByOrderId(orders.getId());
                try {
                    mineDetailVO.setLogisticsTrace(logisticsService.getOrderTracesByJson(orders.getTradeNo(), orders.getLogisticsCompany(), orders.getLogisticsNumber(), orderAddress.getPhone()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }


        UserRelationship userRelationship = userRelationshipMapper.findOneBySubordinateId(user.getId());
        if (userRelationship != null) {
            User result = userMapper.selectByPrimaryKey(userRelationship.getSuperiorId());
            User superior = new User();
            superior.setId(result.getId());
            superior.setUsername(result.getUsername());
            superior.setNickname(result.getNickname());
            superior.setAvatar(result.getAvatar());
            mineDetailVO.setSuperior(superior);
        }

        mineDetailVO.setRewardQueueAmount(rewardQueueMapper.sumByUserIdAndQueueStatusAndRewardStatus(user.getId(), ToggleEnum.OFF.getStatus()));

        mineDetailVO.setMineStatisticsVO(mineStatisticsVO);

        Identity identity = identityMapper.findOneByUserId(user.getId());
        if (user.getLevel() > UserLevelEnum.PARTNER_L4.getLevel()) {
            mineDetailVO.setDirector(identity.getDirector());
        }

        if (identity != null) {
            mineDetailVO.setTeacherLevel(identity.getTeacherLevel());
        }

        MsgUser msgUser = msgUserMapper.findOneByRelateId(user.getId());
        if (msgUser != null) {
            mineDetailVO.setUnreadNum(msgMapper.countByIsReadAndToId(ToggleEnum.OFF.getStatus(), msgUser.getId()));
        }
        mineDetailVO.setRushCount(orderSkuMapper.countByOrderKindAndRushBuyStatusAndUserId(OrderKindEnum.COMMISSION.getKind(), RushBuyStatusEnum.PENDING.getStatus(), user.getId()));

        return new ResultData<>(mineDetailVO);
    }

    @Override
    public BaseResp createTracks(User user, Long spuId) {
        Long count = tracksMapper.countByUserId(user.getId());
        // 只保留最近的30条
        if (count != null && count > MAX_TRACKS_COUNT) {
            tracksMapper.deleteFirstByUserId(user.getId(), count - MAX_TRACKS_COUNT);
        }
        // 先删除今天的，同spu足迹
        tracksMapper.deleteByUserIdAndSpuIdToday(user.getId(), spuId);
        tracksMapper.insert(new Tracks(null, user.getId(), spuId, new Date()));
        return new BaseResp();
    }

    @Override
    public BaseResp deleteTracks(User user, Long id) {
        tracksMapper.deleteByIdAndUserId(id, user.getId());
        return new BaseResp();
    }

    @Override
    public ResultData<UserCollection> createCollection(User user, Long spuId) {
        // 如果超了，用户应该要手动清除收藏
        Long count = userCollectionMapper.countByUserId(user.getId());
        if (count != null && count > MAX_COLLECTION_COUNT) {
            ResultData resultData = new ResultData();
            resultData.setResultCode(ResultCode.OVER_MAX_COLLECTION);
            return resultData;
        }
        UserCollection userCollection = new UserCollection(null, user.getId(), spuId, new Date());
        userCollectionMapper.insert(userCollection);
        return new ResultData<>(userCollection);
    }

    @Override
    public BaseResp deleteCollection(User user, Long id) {
        userCollectionMapper.deleteByIdAndUserId(id, user.getId());
        return new BaseResp();
    }

    @Override
    public ResultData<UserCollection> getCollection(User user, Long spuId) {
        return new ResultData<>(userCollectionMapper.findOneByUserIdAndSpuId(user.getId(), spuId));
    }

    @Override
    public ResultData<BasePageResp<CollectionResp>> getCollectionPage(User user, PageReq req) {
        req.setUserId(user.getId());
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<CollectionResp> list = userCollectionMapper.findAllPage(req);

        if (CollectionUtils.isEmpty(list)) {
            return PageHelpUtil.buildPage(list, page);
        }

        List<Long> spuIds = list.stream().map(UserCollection::getSpuId).collect(Collectors.toList());

        // 获取商品spu信息
        List<Spu> spuList = spuMapper.findAllByIds(spuIds);
        Map<Long, Spu> spuMap = new HashMap<>();
        spuList.stream().forEach(item -> spuMap.put(item.getId(), item));

        list.stream().forEach((item) -> {
            item.setSpuType(spuMap.get(item.getSpuId()).getType());
            item.setMainImage(spuMap.get(item.getSpuId()).getMainImage());
            item.setName(spuMap.get(item.getSpuId()).getName());
            item.setMinPrice(spuMap.get(item.getSpuId()).getMinPrice());
            item.setHidden(spuMap.get(item.getSpuId()).getHidden());
            item.setCategoryId(spuMap.get(item.getSpuId()).getCategoryId());
        });

        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<List<SearchHistory>> getSearchHistory(User user) {
        return new ResultData<>(searchHistoryMapper.findAllByUserId(user.getId()));
    }

    @Override
    public BaseResp createSearchHistory(User user, SearchHistory searchHistory) {
        // 先判断是否已经有此搜索记录，如果有，则更新创建时间
        SearchHistory result = searchHistoryMapper.findOneByUserIdAndContent(user.getId(), searchHistory.getContent());
        if (result == null) {
            // 添加
            // 定时任务，删除1个月以前的搜索记录，查询时只展示最近的20条记录
            if (!StringUtils.isEmpty(searchHistory.getContent())) {
                searchHistory.setUserId(user.getId());
                searchHistory.setCreatedAt(new Date());
                searchHistoryMapper.insert(searchHistory);
            }
        } else {
            // 如果已经有搜索记录了，就更新他的创建时间，这样展示就靠前了
            result.setCreatedAt(new Date());
            searchHistoryMapper.updateByPrimaryKey(result);
        }

        return new BaseResp();
    }

    @Override
    public BaseResp clearSearchHistory(User user) {
        searchHistoryMapper.deleteByUserId(user.getId());
        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<TracksResp>> getTracksPage(User user, PageReq req) {
        req.setUserId(user.getId());
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<TracksResp> list = tracksMapper.findAllPage(req);

        if (CollectionUtils.isEmpty(list)) {
            return PageHelpUtil.buildPage(list, page);
        }

        List<Long> spuIds = list.stream().map(TracksResp::getSpuId).collect(Collectors.toList());

        // 获取商品spu信息
        List<Spu> spuList = spuMapper.findAllByIds(spuIds);
        Map<Long, Spu> spuMap = new HashMap<>();
        spuList.stream().forEach(item -> spuMap.put(item.getId(), item));

        list.stream().forEach((item) -> {
            item.setMainImage(spuMap.get(item.getSpuId()).getMainImage());
            item.setName(spuMap.get(item.getSpuId()).getName());
            item.setMinPrice(spuMap.get(item.getSpuId()).getMinPrice());
            item.setHidden(spuMap.get(item.getSpuId()).getHidden());
            item.setCategoryId(spuMap.get(item.getSpuId()).getCategoryId());
            item.setSpuType(spuMap.get(item.getSpuId()).getType());
        });

        return PageHelpUtil.buildPage(list, page);
    }


    @Override
    public ResultData<BasePageResp<UserCommissionResp>> getCommissionPage(User user, UserCommissionReq req) {
        req.setSuperiorId(user.getId());
        if (req.getTimeType() != null) {
            Calendar startCalendar = Calendar.getInstance();
            startCalendar.setTime(req.getDate());
            Calendar endCalendar = Calendar.getInstance();
            endCalendar.setTime(req.getDate());
            req.setStartTime(getFirstTimeByTimeType(startCalendar, req.getTimeType()));
            req.setEndTime(getEndTimeByTimeType(endCalendar, req.getTimeType()));
        }
        if (CollectionUtils.isEmpty(req.getTypes())) {
            req.setTypes(null);
        }
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<UserCommissionResp> list = userCommissionMapper.findAllPage(req);

        if (CollectionUtils.isEmpty(list)) {
            return PageHelpUtil.buildPage(list, page);
        }
        Map<Long, User> userMap = daoService.getUserMap(list.stream().map(UserCommissionResp::getSubordinateId).collect(Collectors.toList()));

        list.stream().forEach(item -> {
            item.setSubordinateNickname(userMap.get(item.getSubordinateId()).getNickname());
            item.setSubordinateAvatar(userMap.get(item.getSubordinateId()).getAvatar());
            item.setSubordinateLevel(userMap.get(item.getSubordinateId()).getLevel());
        });
        ResultData<BasePageResp<UserCommissionResp>> data = PageHelpUtil.buildPage(list, page);
        if (req.getNeedSum() != null && req.getNeedSum()) {
            StatisticsVO vo = userCommissionMapper.getCommissionPageStatistics(req);
            data.getValue().setExtra(vo);
        }
        return data;
    }

    @Override
    public ResultData<ShareholderVO> getShareholderDetail(User user) {
        Identity identity = identityMapper.findOneByUserId(user.getId());
        if (identity == null || identity.getShareholderLevel().compareTo(9) < 0) {
            ResultData resultData = new ResultData();
            resultData.setResultCode(ResultCode.NOT_SHAREHOLDER);
            return resultData;
        }
        ShareholderVO vo = new ShareholderVO();
        List<Byte> bytes = new ArrayList<>();
        bytes.add(UserCommissionTypeEnum.SHAREHOLDER_GROUP_COMMISSION.getType());
        bytes.add(UserCommissionTypeEnum.SHAREHOLDER_INCOME_COMMISSION.getType());
        bytes.add(UserCommissionTypeEnum.SHAREHOLDER_RECOMMEND_PARTNER_COMMISSION.getType());
        bytes.add(UserCommissionTypeEnum.SHAREHOLDER_ANCHOR_COMMISSION.getType());
        vo.setTotalAmount(userCommissionMapper.getTotalByTypes(user.getId(), bytes));
        vo.setPartnerCount(identity.getPartnerL1Number());
        return new ResultData(vo);
    }

    @Override
    public ResultData<List<IncomeVO>> getMemberAndPartnerIncome(User user, UserGroupReq req) {
        req.setCaptainId(user.getId());
        return new ResultData<>(userGroupMapper.getMemberAndPartnerIncome(req));
    }

    @Override
    public ResultData<BasePageResp<Coupon>> getUserCouponPage(User user, PageReq req) {
        req.setUserId(user.getId());
        req.setNow(new Date());
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<UserCoupon> list = userCouponMapper.findAllPage(req);
        if (CollectionUtils.isEmpty(list)) {
            return PageHelpUtil.buildPage(new ArrayList<>(), page);
        }
        List<Coupon> couponList = couponMapper.findAllByIds(list.stream().map(UserCoupon::getCouponId).collect(Collectors.toList()));
        return PageHelpUtil.buildPage(couponList, page);
    }

    @Override
    public ResultData<Coupon> getUserCouponDetail(Long id) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        List<UserCoupon> userCouponList = userCouponMapper.findAllByUserId(user.getId());
        Coupon coupon = new Coupon();
        if (!CollectionUtils.isEmpty(userCouponList) && userCouponList.stream().map(UserCoupon::getCouponId).collect(Collectors.toList()).contains(id)) {
            coupon = couponMapper.selectByPrimaryKey(id);
        }
        return new ResultData<>(coupon);
    }

    @Override
    public ResultData<String> getStaffCode(User user) {
        ResultData<String> resultData = new ResultData<>();

        Hashids hashids = new Hashids(salt, 32);
        String hash = hashids.encode(user.getId(), System.currentTimeMillis());
        resultData.setValue(hash);
        return resultData;
    }


    @Override
    public BaseResp editBusinessCard(BusinessCard req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (req.getId() == null) {
            req.setUserId(user.getId());
            req.setCreatedAt(new Date());
            req.setUpdatedAt(new Date());
            businessCardMapper.insert(req);
        } else {
            BusinessCard result = businessCardMapper.selectByPrimaryKey(req.getId());
            if (result.getUserId().equals(user.getId())) {
                req.setUpdatedAt(new Date());
                businessCardMapper.updateByPrimaryKeySelective(req);
            }
        }
        return new BaseResp();
    }

    @Override
    public ResultData<BusinessCardVO> getMyBusinessCard(Long userId) {
        BusinessCardVO vo = new BusinessCardVO();
        BusinessCard businessCard = businessCardMapper.findOneByUserId(userId);
        if (businessCard != null) {
            BeanUtils.copyProperties(businessCard, vo);
        }
        User user = userMapper.selectByPrimaryKey(userId);
        vo.setAvatar(user.getAvatar());
        vo.setNickname(user.getNickname());
        vo.setUsername(user.getUsername());

        return new ResultData<>(vo);
    }

    @Override
    public BaseResp closeUser(User user) {
        user.setUsername(user.getId().toString() + user.getUsername());
        user.setOpenid(user.getId().toString() + user.getOpenid());
        user.setPassword(user.getId().toString() + user.getPassword());
        user.setStatus(UserStatusEnum.CLOSE.getStatus());
        user.setLastPasswordResetDate(new Date());
        user.setUpdatedAt(new Date());
        userMapper.updateByPrimaryKey(user);
        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<UserGroupVO>> getUserGroupPage(User user, UserGroupReq req) {
        req.setCaptainId(user.getId());
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<UserGroupVO> list = userGroupMapper.findAllPage(req);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, User> userMap = daoService.getUserMap(list.stream().map(UserGroupVO::getMemberId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setMemberAvatar(userMap.get(item.getMemberId()).getAvatar());
                item.setMemberNickname(userMap.get(item.getMemberId()).getNickname());
            });
        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<BasePageResp<CardFlowVO>> getCardFlowPage(User user, PageReq req) {
        req.setUserId(user.getId());
        Calendar startCalendar = Calendar.getInstance();
        Calendar endCalendar = Calendar.getInstance();
        if (req.getNow() != null) {
            startCalendar.setTime(req.getNow());
            endCalendar.setTime(req.getNow());
            req.setStartTime(getFirstTimeByTimeType(startCalendar, TimeType.MONTH.getType()));
            req.setEndTime(getEndTimeByTimeType(startCalendar, TimeType.MONTH.getType()));
        }

        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<CardFlowVO> list = cardFlowMapper.findAllPage(req);
        if (!CollectionUtils.isEmpty(list)) {
            List<Long> relateIds = list.stream().map(CardFlowVO::getRelateId).filter(Objects::nonNull).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(relateIds)) {
                Map<Long, User> giveUserMap = new HashMap<>();
                if (req.getScene() != null && req.getScene() == 1) {
                    giveUserMap = daoService.getUserMap(relateIds);
                }
                Map<Long, OrderSku> orderSkuMap = daoService.getOrderSkuMap(relateIds);
                List<Long> userIds = orderSkuMap.values().stream().map(OrderSku::getUserId).collect(Collectors.toList());
                Map<Long, User> userMap = new HashMap<>();
                if (!CollectionUtils.isEmpty(userIds)) {
                    userMap = daoService.getUserMap(userIds);
                }
                Map<Long, User> finalGiveUserMap = giveUserMap;
                Map<Long, User> finalUserMap = userMap;
                list.stream().forEach(item -> {
                    if (CardTradeTypeEnum.DIRECT_RECOMMEND_REWARD.getTradeType().equals(item.getTradeType())) {
                        if (finalUserMap.containsKey(item.getRelateId())) {
                            item.setNickname(finalUserMap.get(orderSkuMap.get(item.getRelateId()).getUserId()).getNickname());
                            item.setAvatar(finalUserMap.get(orderSkuMap.get(item.getRelateId()).getUserId()).getAvatar());
                        }
                    }
                    if (CardTradeTypeEnum.PAY.getTradeType().equals(item.getTradeType()) || CardTradeTypeEnum.CLOSE_ORDER.getTradeType().equals(item.getTradeType())) {
                        if (orderSkuMap.containsKey(item.getRelateId())) {
                            item.setSpuId(orderSkuMap.get(item.getRelateId()).getSpuId());
                        }
                    }
                    if (req.getScene() != null && req.getScene() == 1) {
                        if (finalGiveUserMap.containsKey(item.getRelateId())) {
                            User giveUser = finalGiveUserMap.get(item.getRelateId());

                            if (CardTradeTypeEnum.TRANSFER_ACCOUNTS_REWARD.getTradeType().equals(item.getTradeType())) {
                                item.setFromNickname(giveUser.getNickname());
                                item.setFromAvatar(giveUser.getAvatar());
                            }
                            if (CardTradeTypeEnum.TRANSFER_ACCOUNTS_REFUND.getTradeType().equals(item.getTradeType())) {
                                item.setGiveNickname(giveUser.getNickname());
                                item.setGiveAvatar(giveUser.getAvatar());
                            }
                        }
                    }
                });
            }


        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<IdentityResp> getUserIdentity(User user) {
        IdentityResp resp = new IdentityResp();
        Identity identity = identityMapper.findOneByUserId(user.getId());
        if (identity != null) {
            BeanUtils.copyProperties(identity, resp);
            BigDecimal releaseAmount = welfareFlowMapper.sumReleaseAmount(user.getId());
            resp.setReleaseWelfare(releaseAmount != null ? releaseAmount : BigDecimal.ZERO);
        }
        return new ResultData<>(resp);
    }

    @Override
    public ResultData<GroupVO> getUserGroup(User user, ListByTimeReq req) {
        req.setSuperiorId(user.getId());
        GroupVO groupVO = userRelationshipMapper.getUserGroupCount(req);
        if (groupVO != null) {
            groupVO = new GroupVO();
        }
        List<UserRelationshipVO> list = userRelationshipMapper.getUserGroupList(req);

        if (!list.isEmpty()) {
            Map<Long, User> userMap = daoService.getUserMap(list.stream().map(UserRelationshipVO::getSubordinateId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setSubordinateAvatar(userMap.get(item.getSubordinateId()).getAvatar());
                item.setSubordinateNickname(userMap.get(item.getSubordinateId()).getNickname());
            });
        }
        groupVO.setGroupList(list);

        Long superiorId = userRelationshipMapper.findSuperiorIdBySubordinateId(user.getId());
        groupVO.setRecommendedNickname(superiorId != null ? userMapper.selectByPrimaryKey(superiorId).getNickname() : null);
        return new ResultData<>(groupVO);
    }

    @Override
    public ResultData<MoneyInfoResp> getUserMoneyInfo(User user, Byte businessType) {
        MoneyInfoResp moneyInfoResp = new MoneyInfoResp();

        List<Byte> list = new ArrayList<>();

        list.add(UserCommissionTypeEnum.SHAREHOLDER_L2_DIVIDENDS.getType());
        list.add(UserCommissionTypeEnum.SHAREHOLDER_L3_DIVIDENDS.getType());
        list.add(UserCommissionTypeEnum.SHAREHOLDER_L4_DIVIDENDS.getType());

        moneyInfoResp.setTotalBonus(userCommissionMapper.getTotalByTypes(user.getId(), list));

        list.clear();
        list.add(UserCommissionTypeEnum.MEMBER_SHARE_COMMISSION.getType());
        list.add(UserCommissionTypeEnum.PARTNER_SHARE_COMMISSION.getType());
        list.add(UserCommissionTypeEnum.SHAREHOLDER_SHARE_COMMISSION.getType());

        moneyInfoResp.setTotalDistribution(userCommissionMapper.getTotalByTypes(user.getId(), list));

        moneyInfoResp.setInList(userCommissionMapper.getTotalIncomeByMonth(user.getId()));
        moneyInfoResp.setOutList(withdrawMapper.getWithdrawByMonth(user.getId(), WithdrawStatusEnum.SUCCESS.getStatus()));

        moneyInfoResp.setPoint(user.getPoint());
        BigDecimal totalFreeze = userCommissionMapper.sumFreeze(user.getId(), UserCommissionStatusEnum.FREEZE.getStatus(), businessType);
        moneyInfoResp.setTotalFreeze(totalFreeze != null ? totalFreeze : BigDecimal.ZERO);
        moneyInfoResp.setProcessingWithdraw(withdrawMapper.sumByUserIdAndStatus(user.getId(), WithdrawStatusEnum.PROCESSING.getStatus(), businessType));
        moneyInfoResp.setTotalWithdraw(withdrawMapper.sumByUserIdAndStatus(user.getId(), WithdrawStatusEnum.SUCCESS.getStatus(), businessType));

        if (BusinessTypeEnum.USER.getType().equals(businessType)) {
            BigDecimal userAmount = withdrawMapper.sumByUserIdAndStatusAndBusinessType(user.getId(), WithdrawStatusEnum.SUCCESS.getStatus(), BusinessTypeEnum.USER.getType());
            BigDecimal userIssue = userCommissionMapper.sumByUserIdAndBusinessTypeAndStatus(user.getId(), BusinessTypeEnum.USER.getType(), UserCommissionStatusEnum.ISSUED.getStatus());
            //转换成嗨币支出
            BigDecimal change = balanceFlowMapper.sumByUserIdAndTradeType(user.getId(), TradeTypeEnum.POINT_TO_CARD_POINT.getTradeType());
            if (userAmount == null) {
                userAmount = BigDecimal.ZERO;
            }
            if (userIssue == null) {
                userIssue = BigDecimal.ZERO;
            }
            if (change == null) {
                change = BigDecimal.ZERO;
            }
            moneyInfoResp.setPoint(userIssue.subtract(userAmount).subtract(change));
        } else {
            BigDecimal shopAmount = withdrawMapper.sumByUserIdAndStatusAndBusinessType(user.getId(), WithdrawStatusEnum.SUCCESS.getStatus(), BusinessTypeEnum.SHOP.getType());
            BigDecimal shopIssue = userCommissionMapper.sumByUserIdAndBusinessTypeAndStatus(user.getId(), BusinessTypeEnum.SHOP.getType(), UserCommissionStatusEnum.ISSUED.getStatus());

            if (shopAmount == null) {
                shopAmount = BigDecimal.ZERO;
            }
            if (shopIssue == null) {
                shopIssue = BigDecimal.ZERO;
            }

            moneyInfoResp.setPoint(shopIssue.subtract(shopAmount));
        }

        return new ResultData<>(moneyInfoResp);
    }

    @Override
    public ResultData<List<UserMoneyStatisticsVO>> getUserMoneyStatistics(User user) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        List<UserMoneyStatisticsVO> list = new ArrayList<>();
        calendar.add(Calendar.MONTH, -5);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        list = userCommissionMapper.getUserMoneyIncomeStatistics(user.getId(), getFirstTime(calendar).getTime());
        return new ResultData<>(list);
    }

    @Override
    public ResultData<IncomeInfoVO> getUserBonusInfo(User user) {
        List<Byte> list = new ArrayList<>();

        list.add(UserCommissionTypeEnum.PARTNER_L2_DIVIDENDS.getType());
        list.add(UserCommissionTypeEnum.PARTNER_L3_DIVIDENDS.getType());
        list.add(UserCommissionTypeEnum.PARTNER_L4_DIVIDENDS.getType());

        list.add(UserCommissionTypeEnum.SHAREHOLDER_L2_DIVIDENDS.getType());
        list.add(UserCommissionTypeEnum.SHAREHOLDER_L3_DIVIDENDS.getType());
        list.add(UserCommissionTypeEnum.SHAREHOLDER_L4_DIVIDENDS.getType());


        list.add(UserCommissionTypeEnum.SHOP_COMMISSION.getType());

        return new ResultData<>(IncomeInfoVO.builder().incomeTimeVO(userCommissionMapper.getIncomeTime(user.getId(), list)).build());
    }

    @Override
    public ResultData<IncomeInfoVO> getUserDistributionInfo(User user) {
        List<Byte> list = new ArrayList<>();
        list.add(UserCommissionTypeEnum.MEMBER_SHARE_COMMISSION.getType());
        list.add(UserCommissionTypeEnum.PARTNER_SHARE_COMMISSION.getType());
        list.add(UserCommissionTypeEnum.SHAREHOLDER_SHARE_COMMISSION.getType());

        return new ResultData<>(IncomeInfoVO.builder().incomeTimeVO(userCommissionMapper.getIncomeTime(user.getId(), list)).build());
    }

    @Override
    public ResultData<IncomeDetailVO> getIncomeCount(User user, ListByTimeReq req) {
        String value = daoService.getHipoConfigValue(HipoConfigEnum.SINGLE_SHOP_SHAREHOLDER_COUNT.getConfig());
        NumberByTypeVO numberByTypeVO = identityMapper.getNumber(req);
        numberByTypeVO.setSingleShopNumber(Long.valueOf(value));

        IncomeDetailVO incomeDetailVO = IncomeDetailVO.builder().amount(BigDecimal.ZERO).numberByTypeVO(numberByTypeVO).amountByTypeVO(userCommissionMapper.getAmount(req)).total(0L).build();
        req.setSuperiorId(user.getId());
        List<CountByTypeVO> list = userCommissionMapper.getIncomeCount(req);

        if (!list.isEmpty()) {
            Map<String, String> hipoConfigMap = daoService.getHipoConfigMap();

            list.stream().forEach(item -> {
                incomeDetailVO.setAmount(incomeDetailVO.getAmount().add(item.getAmount()));
                incomeDetailVO.setTotal(incomeDetailVO.getTotal() + item.getTotal());

                switch (UserCommissionTypeEnum.getByType(item.getType())) {
                    case MEMBER_L2_DIVIDENDS:
                        item.setDivided(hipoConfigMap.get(HipoConfigEnum.MEMBER_DIVIDENDS_1_RATE.getConfig()));
                        break;
                    case MEMBER_L3_DIVIDENDS:
                        item.setDivided(hipoConfigMap.get(HipoConfigEnum.MEMBER_DIVIDENDS_2_RATE.getConfig()));
                        break;
                    case MEMBER_L4_DIVIDENDS:
                        item.setDivided(hipoConfigMap.get(HipoConfigEnum.MEMBER_DIVIDENDS_3_RATE.getConfig()));
                        break;
                    case PARTNER_L2_DIVIDENDS:
                        item.setDivided(hipoConfigMap.get(HipoConfigEnum.PARTNER_DIVIDENDS_1_RATE.getConfig()));
                        break;
                    case PARTNER_L3_DIVIDENDS:
                        item.setDivided(hipoConfigMap.get(HipoConfigEnum.PARTNER_DIVIDENDS_2_RATE.getConfig()));
                        break;
                    case PARTNER_L4_DIVIDENDS:
                        item.setDivided(hipoConfigMap.get(HipoConfigEnum.PARTNER_DIVIDENDS_3_RATE.getConfig()));
                        break;
                    case SHAREHOLDER_L2_DIVIDENDS:
                        item.setDivided(hipoConfigMap.get(HipoConfigEnum.SHAREHOLDER_DIVIDENDS_1_RATE.getConfig()));
                        break;
                    case SHAREHOLDER_L3_DIVIDENDS:
                        item.setDivided(hipoConfigMap.get(HipoConfigEnum.SHAREHOLDER_DIVIDENDS_2_RATE.getConfig()));
                        break;
                    case SHAREHOLDER_L4_DIVIDENDS:
                        item.setDivided(hipoConfigMap.get(HipoConfigEnum.SHAREHOLDER_DIVIDENDS_3_RATE.getConfig()));
                        break;
                    case MEMBER_SHARE_COMMISSION:
                        item.setDivided(hipoConfigMap.get(HipoConfigEnum.MEMBER_COMMISSION_RATE.getConfig()));
                        break;
                    case PARTNER_SHARE_COMMISSION:
                        item.setDivided(hipoConfigMap.get(HipoConfigEnum.PARTNER_COMMISSION_RATE.getConfig()));
                        break;
                    case SHAREHOLDER_SHARE_COMMISSION:
                        item.setDivided(hipoConfigMap.get(HipoConfigEnum.SHAREHOLDER_COMMISSION_RATE.getConfig()));
                        break;
                    case PARTNER_GROUP_COMMISSION:
                        item.setDivided(hipoConfigMap.get(HipoConfigEnum.PARTNER_GROUP_REWARD_RATE.getConfig()));
                        break;
                    case SHAREHOLDER_GROUP_COMMISSION:
                        item.setDivided(hipoConfigMap.get(HipoConfigEnum.SHAREHOLDER_GROUP_REWARD_RATE.getConfig()));
                        break;
                    case SHOP_COMMISSION:
                        item.setDivided(hipoConfigMap.get(HipoConfigEnum.SINGLE_SHOP_DIVIDENDS_RATE.getConfig()));
                        break;
                    default:
                        break;
                }
            });
        }

        incomeDetailVO.setList(list);
        return new ResultData<>(incomeDetailVO);

    }

    @Override
    public BaseResp createInformation(Information information) {
        informationMapper.insert(information);
        return new BaseResp();
    }

    @Override
    public BaseResp editShopApply(User user, Shop req) {
        ShopApply old = shopApplyMapper.findOneByUserIdAndDeleted(user.getId(), DeletedEnum.DEFAULT.getStatus());
        if (old == null) {
            ShopApply shopApply = new ShopApply();

            Shop shop = shopMapper.findOneByPhone(req.getPhone());
            if (shop != null) {
                return new BaseResp(ResultCode.PHONE_EXISTS);
            }
            if (req.getKind() == null) {
                req.setKind(ShopKindEnum.PROJECT.getKind());
            }
            insertExtracted(req, shopApply, user);
            shopApply.setCount(shopApply.getCount() + 1);
            shopApplyMapper.insert(shopApply);
        } else {
            req.setId(old.getId());
            old.setCount(old.getCount() + 1);
            extracted(req, old, user);
            old.setUpdatedAt(new Date());
            shopApplyMapper.updateByPrimaryKeySelective(old);
        }
        return new BaseResp();
    }

    private static void extracted(Shop req, ShopApply shopApply, User user) {
        shopApply.setId(req.getId() == null ? null : req.getId());
        shopApply.setUserId(user.getId());
        shopApply.setPermitImage(req.getPermitImage());
        shopApply.setLogo(req.getLogo());
        shopApply.setProvince(req.getProvince());
        shopApply.setTypeName(req.getTypeName());
        shopApply.setAvatar(req.getAvatar());
        shopApply.setArea(req.getArea());
        shopApply.setCity(req.getCity());
        shopApply.setAccount(req.getAccount());
        shopApply.setLicenseValidTime(req.getLicenseValidTime());
        shopApply.setBank(req.getBank());
        shopApply.setOpenBank(req.getOpenBank());
        shopApply.setOpenName(req.getOpenName());
        shopApply.setMergerName(req.getMergerName());
        shopApply.setLicenseNumber(req.getLicenseNumber());
        shopApply.setLicenseImage(req.getLicenseImage());
        shopApply.setLicenseAddress(req.getAddress());
        shopApply.setLicenseLongTerm(req.getLicenseLongTerm());
        shopApply.setKind(req.getKind());
        shopApply.setShopType(req.getShopType());
        shopApply.setName(req.getName());
        shopApply.setLongitude(req.getLongitude());
        shopApply.setLocation(req.getLocation());
        shopApply.setPhone(req.getPhone());
        if (shopApply.getCount() > 2) {
            shopApply.setAuditStatus((byte) 0);
        } else {
            shopApply.setAuditStatus((byte) 3);
        }
        shopApply.setTenantName(req.getShopName());
        shopApply.setLatitude(req.getLatitude());
        shopApply.setAddress(req.getAddress());
        shopApply.setIdCardName(req.getIdCardName());
        shopApply.setTypeId(req.getTypeId());
        shopApply.setIdCardNumber(req.getIdCardNumber());
        shopApply.setIdCardBack(req.getIdCardBack());
        shopApply.setIdCardPositive(req.getIdCardPositive());
        shopApply.setFrontImage(req.getAvatar());
        shopApply.setEnvironmentImage(req.getEnvironmentImage());
        shopApply.setApplyType(req.getApplyType());
        shopApply.setIdCardCode(req.getIdCardCode());
        shopApply.setCertificateType(req.getCertificateType());
        shopApply.setDeleted(req.getDeleted());
        shopApply.setIndustryFirstId(req.getIndustryFirstId());
        shopApply.setIndustrySecondId(req.getIndustrySecondId());
        shopApply.setApplyType(req.getApplyType());
    }

    private static void insertExtracted(Shop req, ShopApply shopApply, User user) {
        shopApply.setId(req.getId() == null ? null : req.getId());
        shopApply.setUserId(user.getId());
        shopApply.setPermitImage(req.getPermitImage());
        shopApply.setLogo(req.getLogo());
        shopApply.setProvince(req.getProvince());
        shopApply.setTypeName(req.getTypeName());
        shopApply.setAvatar(req.getAvatar());
        shopApply.setArea(req.getArea());
        shopApply.setCity(req.getCity());
        shopApply.setAccount(req.getAccount());
        shopApply.setLicenseValidTime(req.getLicenseValidTime());
        shopApply.setBank(req.getBank());
        shopApply.setOpenBank(req.getOpenBank());
        shopApply.setOpenName(req.getOpenName());
        shopApply.setMergerName(req.getMergerName());
        shopApply.setLicenseNumber(req.getLicenseNumber());
        shopApply.setLicenseImage(req.getLicenseImage());
        shopApply.setLicenseAddress(req.getAddress());
        shopApply.setLicenseLongTerm(req.getLicenseLongTerm());
        shopApply.setKind(req.getKind());
        shopApply.setShopType(req.getShopType());
        shopApply.setName(req.getName());
        shopApply.setLongitude(req.getLongitude());
        shopApply.setLocation(req.getLocation());
        shopApply.setPhone(req.getPhone());
        shopApply.setAuditStatus((byte) 3);
        shopApply.setTenantName(req.getShopName());
        shopApply.setLatitude(req.getLatitude());
        shopApply.setAddress(req.getAddress());
        shopApply.setIdCardName(req.getIdCardName());
        shopApply.setTypeId(req.getTypeId());
        shopApply.setIdCardNumber(req.getIdCardNumber());
        shopApply.setIdCardBack(req.getIdCardBack());
        shopApply.setIdCardPositive(req.getIdCardPositive());
        shopApply.setIsRead((byte) 1);
        shopApply.setFrontImage(req.getAvatar());
        shopApply.setEnvironmentImage(req.getEnvironmentImage());
        shopApply.setApplyType(req.getApplyType());
        shopApply.setIdCardCode(req.getIdCardCode());
        shopApply.setCertificateType(req.getCertificateType());
        shopApply.setCreatedAt(new Date());
        shopApply.setDeleted(DeletedEnum.DEFAULT.getStatus());
        shopApply.setIndustryFirstId(req.getIndustryFirstId());
        shopApply.setIndustrySecondId(req.getIndustrySecondId());
        shopApply.setApplyType((byte) 2);
    }

    @Override
    public ResultData<ShopApply> getShopApply(User user) {
        return new ResultData<>(shopApplyMapper.findOneByUserIdAndDeleted(user.getId(), DeletedEnum.DEFAULT.getStatus()));
    }

    @Override
    public ResultData<CoinCountVO> getCoinCount(User user) {

        CoinCountVO coinCountVO = coinFlowMapper.getCoinCount(user.getId());

        if (coinCountVO == null) {
            coinCountVO = new CoinCountVO();
        }

        coinCountVO.setTotal(user.getCoin());
        coinCountVO.setInsByTime(coinFlowMapper.getCoinCountByType((byte) 0, user.getId()));
        coinCountVO.setOutsByTime(coinFlowMapper.getCoinCountByType((byte) 1, user.getId()));
        coinCountVO.setIns(coinFlowMapper.findAllPage(PageReq.builder().pageSize(5).type((byte) 0).userId(user.getId()).build()));
        coinCountVO.setOuts(coinFlowMapper.findAllPage(PageReq.builder().pageSize(5).type((byte) 1).userId(user.getId()).build()));
        return new ResultData<>(coinCountVO);
    }

    @Override
    public ResultData<AutomaticFreeListVO> getAutomaticFree(Integer level) {

        List<UserSimpleVO> freeList = rewardQueueMapper.findAllByLevelAndQueueStatus(level, ToggleEnum.ON.getStatus(), 10L);
        List<UserSimpleVO> buyerList = identityMapper.getBuyerList(level);
        List<Long> ids = new ArrayList<>();
        if (!freeList.isEmpty()) {
            ids.addAll(freeList.stream().map(UserSimpleVO::getUserId).collect(Collectors.toList()));
        }
        if (!buyerList.isEmpty()) {
            ids.addAll(buyerList.stream().map(UserSimpleVO::getUserId).collect(Collectors.toList()));
        }

        if (!ids.isEmpty()) {
            Map<Long, User> userMap = daoService.getUserMap(ids);

            if (!freeList.isEmpty()) {
                freeList.stream().forEach(item -> {
                    item.setNickname(userMap.get(item.getUserId()).getNickname());
                    item.setAvatar(userMap.get(item.getUserId()).getAvatar());
                });
            }
            if (!buyerList.isEmpty()) {
                buyerList.stream().forEach(item -> {
                    item.setAvatar(userMap.get(item.getUserId()).getAvatar());
                    item.setNickname(userMap.get(item.getUserId()).getNickname());
                });
            }
        }
        Spu spu = new Spu();
        if (UserLevelEnum.MEMBER_L1.getLevel().equals(level)) {
            String spuId = daoService.getHipoConfigValue(HipoConfigEnum.MEMBER_SPU.getConfig());
            spu = spuMapper.selectByPrimaryKey(Long.valueOf(spuId));
        } else if (UserLevelEnum.PARTNER_L1.getLevel().equals(level)) {
            String spuId = daoService.getHipoConfigValue(HipoConfigEnum.PARTNER_SPU.getConfig());
            spu = spuMapper.selectByPrimaryKey(Long.valueOf(spuId));
        } else {
            String spuId = daoService.getHipoConfigValue(HipoConfigEnum.SHAREHOLDER_SPU.getConfig());
            spu = spuMapper.selectByPrimaryKey(Long.valueOf(spuId));
        }

        return new ResultData<>(AutomaticFreeListVO.builder().freeList(freeList).buyerList(buyerList).spu(spu).build());
    }

    @Override
    public ResultData<WaitFreeVO> getWaitFree(User user, Integer level) {
        WaitFreeVO waitFreeVO = rewardQueueMapper.getWaitFree(level);
        List<UserSimpleVO> list = rewardQueueMapper.findAllByLevelAndQueueStatus(level, ToggleEnum.ON.getStatus(), 4L);
        Map<String, String> hipoConfigMap = daoService.getHipoConfigMap();


        BigDecimal bonus = new BigDecimal(BigInteger.ZERO);
        if (UserLevelEnum.MEMBER_L1.getLevel().equals(level)) {
            bonus = new BigDecimal(hipoConfigMap.get(HipoConfigEnum.MEMBER_PRICE.getConfig()));
        } else if (UserLevelEnum.PARTNER_L1.getLevel().equals(level)) {
            bonus = new BigDecimal(hipoConfigMap.get(HipoConfigEnum.PARTNER_PRICE.getConfig()));
        } else if (UserLevelEnum.SHAREHOLDER_L1.getLevel().equals(level)) {
            bonus = new BigDecimal(hipoConfigMap.get(HipoConfigEnum.SHAREHOLDER_PRICE.getConfig()));
        } else if (UserLevelEnum.MEMBER_L4.getLevel().equals(level)) {
            bonus = new BigDecimal(hipoConfigMap.get(HipoConfigEnum.MEMBER_L4_BONUS.getConfig()));
        } else if (UserLevelEnum.PARTNER_L4.getLevel().equals(level)) {
            bonus = new BigDecimal(hipoConfigMap.get(HipoConfigEnum.PARTNER_L4_BONUS.getConfig()));
        } else if (UserLevelEnum.SHAREHOLDER_L4.getLevel().equals(level)) {
            bonus = new BigDecimal(hipoConfigMap.get(HipoConfigEnum.SHAREHOLDER_L4_BONUS.getConfig()));
        }
        waitFreeVO.setBonus(bonus);

        if (!list.isEmpty()) {
            Map<Long, User> userMap = daoService.getUserMap(list.stream().map(UserSimpleVO::getUserId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setNickname(userMap.get(item.getUserId()).getNickname());
                item.setAvatar(userMap.get(item.getUserId()).getAvatar());
            });
        }

        waitFreeVO.setList(list);
        return new ResultData<>(waitFreeVO);
    }


    private Calendar getFirstTime(Calendar calendar) {
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        return calendar;
    }

    private Date getFirstTimeByTimeType(Calendar calendar, Byte timeType) {
        if (timeType.equals(TimeType.DAY.getType())) {
            return getFirstTime(calendar).getTime();
        } else if (timeType.equals(TimeType.WEEK.getType())) {
            calendar.setFirstDayOfWeek(Calendar.MONDAY);
            calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            return getFirstTime(calendar).getTime();
        } else if (timeType.equals(TimeType.MONTH.getType())) {
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            return getFirstTime(calendar).getTime();
        } else {
            calendar.set(Calendar.DAY_OF_YEAR, calendar.getActualMinimum(Calendar.DAY_OF_YEAR));
            return getFirstTime(calendar).getTime();
        }
    }

    private Date getEndTimeByTimeType(Calendar calendar, Byte timeType) {
        if (timeType.equals(TimeType.DAY.getType())) {
            calendar.add(Calendar.DATE, +1);
            return getFirstTime(calendar).getTime();
        } else if (timeType.equals(TimeType.WEEK.getType())) {
            calendar.setFirstDayOfWeek(Calendar.MONDAY);
            calendar.add(Calendar.DATE, 7);
            calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            return getFirstTime(calendar).getTime();
        } else if (timeType.equals(TimeType.MONTH.getType())) {
            calendar.add(Calendar.MONTH, +1);
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            return getFirstTime(calendar).getTime();
        } else {
            calendar.add(Calendar.YEAR, +1);
            calendar.set(Calendar.DAY_OF_YEAR, calendar.getActualMinimum(Calendar.DAY_OF_YEAR));
            return getFirstTime(calendar).getTime();
        }
    }


    @Override
    public ResultData<BasePageResp<BalanceFlow>> getBalanceFlowPage(TimeTypeReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        req.setUserId(user.getId());
        Calendar startCalendar = Calendar.getInstance();
        Calendar endCalendar = Calendar.getInstance();
        Date date = req.getDate();
        Byte timeType = req.getTimeType();
        if (date == null) {
            date = new Date();
        }
        startCalendar.setTime(date);
        endCalendar.setTime(date);
        List<BalanceFlow> list = new ArrayList<>();
        if (TimeType.DAY.getType().equals(timeType)) {
            //本日明细
            endCalendar.add(Calendar.DATE, +1);
            req.setStartTime(getFirstTime(startCalendar).getTime());
            req.setEndTime(getFirstTime(endCalendar).getTime());
        } else if (TimeType.WEEK.getType().equals(timeType)) {
            //本周明细
            startCalendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            endCalendar.add(Calendar.WEEK_OF_YEAR, +1);
            endCalendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            req.setStartTime(getFirstTime(startCalendar).getTime());
            req.setEndTime(getFirstTime(endCalendar).getTime());
        } else if (TimeType.MONTH.getType().equals(timeType)) {
            //本月明细
            startCalendar.set(Calendar.DAY_OF_MONTH, 1);
            endCalendar.add(Calendar.MONTH, +1);
            endCalendar.set(Calendar.DAY_OF_MONTH, 1);
            req.setStartTime(getFirstTime(startCalendar).getTime());
            req.setEndTime(getFirstTime(endCalendar).getTime());
        } else if (TimeType.YEAR.getType().equals(timeType)) {
            //本年明细
            startCalendar.set(Calendar.DAY_OF_YEAR, startCalendar.getActualMinimum(Calendar.DAY_OF_YEAR));
            endCalendar.add(Calendar.YEAR, +1);
            endCalendar.set(Calendar.DAY_OF_YEAR, endCalendar.getActualMinimum(Calendar.DAY_OF_YEAR));
            req.setStartTime(getFirstTime(startCalendar).getTime());
            req.setEndTime(getFirstTime(endCalendar).getTime());
        } else {
            req.setStartTime(null);
            req.setEndTime(null);
        }
        list = balanceFlowMapper.findAllPage(req);
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<CountVO> getBalanceFlowCount(TimeTypeReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Calendar calendar = Calendar.getInstance();
        req.setUserId(user.getId());
        if (req.getTimeType() == null) {
            req.setTimeType(TimeType.YEAR.getType());
        }
        if (req.getDate() == null) {
            req.setDate(new Date());
        }
        calendar.setTime(req.getDate());
        req.setStartTime(getFirstTimeByTimeType(calendar, req.getTimeType()));
        req.setEndTime(getEndTimeByTimeType(calendar, req.getTimeType()));
        return new ResultData<>(balanceFlowMapper.getInAndOut(req));
    }

    @Override
    public ResultData<List<BalanceFlowStatisticsVO>> getBalanceFlowStatistics(Byte type) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        List<BalanceFlowStatisticsVO> list = new ArrayList<>();
        calendar.add(Calendar.MONTH, -6);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        list = balanceFlowMapper.getBalanceFlowStatistics(user.getId(), type, getFirstTime(calendar).getTime());
        return new ResultData<>(list);
    }


    @Override
    public ResultData<BalanceFlowCountAndMoneyVO> getBalanceFlowCountAndMoney(TimeTypeReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        req.setUserId(user.getId());
        Calendar startCalendar = Calendar.getInstance();
        Calendar endCalendar = Calendar.getInstance();
        Date date = req.getDate();
        Byte timeType = req.getTimeType();
        if (date == null) {
            date = new Date();
        }
        startCalendar.setTime(date);
        endCalendar.setTime(date);
        BalanceFlowCountAndMoneyVO vo = new BalanceFlowCountAndMoneyVO();
        if (TimeType.DAY.getType().equals(timeType)) {
            //本日明细
            endCalendar.add(Calendar.DATE, +1);
            req.setStartTime(getFirstTime(startCalendar).getTime());
            req.setEndTime(getFirstTime(endCalendar).getTime());
            vo = balanceFlowMapper.getBalanceFlowCountAndMoney(req);
        } else if (TimeType.WEEK.getType().equals(timeType)) {
            //本周明细
            startCalendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            endCalendar.add(Calendar.WEEK_OF_YEAR, +1);
            endCalendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            req.setStartTime(getFirstTime(startCalendar).getTime());
            req.setEndTime(getFirstTime(endCalendar).getTime());
            vo = balanceFlowMapper.getBalanceFlowCountAndMoney(req);
        } else if (TimeType.MONTH.getType().equals(timeType)) {
            //本月明细
            startCalendar.set(Calendar.DAY_OF_MONTH, 1);
            endCalendar.add(Calendar.MONTH, +1);
            endCalendar.set(Calendar.DAY_OF_MONTH, 1);
            req.setStartTime(getFirstTime(startCalendar).getTime());
            req.setEndTime(getFirstTime(endCalendar).getTime());
            vo = balanceFlowMapper.getBalanceFlowCountAndMoney(req);
        } else if (TimeType.YEAR.getType().equals(timeType)) {
            //本年明细
            startCalendar.set(Calendar.DAY_OF_YEAR, startCalendar.getActualMinimum(Calendar.DAY_OF_YEAR));
            endCalendar.add(Calendar.YEAR, +1);
            endCalendar.set(Calendar.DAY_OF_YEAR, endCalendar.getActualMinimum(Calendar.DAY_OF_YEAR));
            req.setStartTime(getFirstTime(startCalendar).getTime());
            req.setEndTime(getFirstTime(endCalendar).getTime());
            vo = balanceFlowMapper.getBalanceFlowCountAndMoney(req);
        } else {
            req.setStartTime(null);
            req.setEndTime(null);
        }
        return new ResultData<>(vo);
    }


    @Override
    public ResultData<List<Catalog>> getCatalogList() {
        return new ResultData<>(catalogMapper.findAll());
    }

    @Override
    public ResultData<List<DirectPushIncomeVO>> getUserCommission(User user) {
        List<DirectPushIncomeVO> directPushIncomeVOList = new ArrayList<>();
        Identity userIdentity = identityMapper.findOneByUserId(user.getId());

        if (userIdentity != null) {
            //当前身份的会员等级是否不为0
            if (!userIdentity.getMemberLevel().equals(UserLevelEnum.CUSTOMER.getLevel())) {
                DirectPushIncomeVO directPushIncomeVO = new DirectPushIncomeVO();
                directPushIncomeVO = userCommissionMapper.getUserCommission(user.getId(), IdentityTypeEnum.MEMBER.getType());
                directPushIncomeVO.setIdentityType(IdentityTypeEnum.MEMBER.getType());
                directPushIncomeVOList.add(directPushIncomeVO);
            }
            //当前身份的合伙人等级是否不为0
            if (!userIdentity.getPartnerLevel().equals(UserLevelEnum.CUSTOMER.getLevel())) {
                DirectPushIncomeVO directPushIncomeVO = new DirectPushIncomeVO();
                directPushIncomeVO = userCommissionMapper.getUserCommission(user.getId(), IdentityTypeEnum.PARTNER.getType());
                directPushIncomeVO.setIdentityType(IdentityTypeEnum.PARTNER.getType());
                directPushIncomeVOList.add(directPushIncomeVO);
            }
            //当前身份的股东等级是否不为0
            if (!userIdentity.getShareholderLevel().equals(UserLevelEnum.CUSTOMER.getLevel())) {
                DirectPushIncomeVO directPushIncomeVO = new DirectPushIncomeVO();
                directPushIncomeVO = userCommissionMapper.getUserCommission(user.getId(), IdentityTypeEnum.SHAREHOLDER.getType());
                directPushIncomeVO.setIdentityType(IdentityTypeEnum.SHAREHOLDER.getType());
                directPushIncomeVOList.add(directPushIncomeVO);
            }
        }

        return new ResultData<>(directPushIncomeVOList);
    }

    @Override
    public ResultData<DirectPushIncomeVO> getTotalUserCommission(User user) {
        Long supereriorId = user.getId();
        DirectPushIncomeVO directPushIncomeVO = userCommissionMapper.getTotalUserCommission(supereriorId);
        return new ResultData<>(directPushIncomeVO);
    }

    @Override
    public ResultData<BasePageResp<DirectPushIncomeVO>> getUserCommissionDetailByTimeType(UserCommissionReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        //获取传入的日期
        Calendar startCalendar = Calendar.getInstance();
        Calendar endCalendar = Calendar.getInstance();
        Date date = req.getDate();
        Byte timeType = req.getTimeType();
        Long superiorId = user.getId();
        if (date == null) {
            date = new Date();
        }
        startCalendar.setTime(date);
        endCalendar.setTime(date);
        List<DirectPushIncomeVO> list = new ArrayList<>();
        if (TimeType.DAY.getType().equals(timeType)) {
            //本日明细
            getFirstTime(startCalendar);
            endCalendar.add(Calendar.DATE, +1);
            getFirstTime(endCalendar);
            list = userCommissionMapper.getUserCommissionDetailByTimeType(startCalendar.getTime(), endCalendar.getTime(), superiorId);
        } else if (TimeType.WEEK.getType().equals(timeType)) {
            //本周明细
            getFirstTime(startCalendar);
            startCalendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            getFirstTime(endCalendar);
            endCalendar.add(Calendar.WEEK_OF_YEAR, +1);
            endCalendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            getFirstTime(endCalendar);
            list = userCommissionMapper.getUserCommissionDetailByTimeType(startCalendar.getTime(), endCalendar.getTime(), superiorId);
        } else if (TimeType.MONTH.getType().equals(timeType)) {
            //本月明细
            getFirstTime(startCalendar);
            startCalendar.set(Calendar.DAY_OF_MONTH, 1);
            getFirstTime(endCalendar);
            endCalendar.add(Calendar.MONTH, +1);
            endCalendar.set(Calendar.DAY_OF_MONTH, 1);
            list = userCommissionMapper.getUserCommissionDetailByTimeType(startCalendar.getTime(), endCalendar.getTime(), superiorId);
        } else if (TimeType.MONTH.getType().equals(timeType)) {
            //本年明细
            getFirstTime(startCalendar);
            startCalendar.set(Calendar.DAY_OF_YEAR, startCalendar.getActualMinimum(Calendar.DAY_OF_YEAR));
            getFirstTime(endCalendar);
            endCalendar.add(Calendar.YEAR, +1);
            endCalendar.set(Calendar.DAY_OF_YEAR, endCalendar.getActualMinimum(Calendar.DAY_OF_YEAR));
            list = userCommissionMapper.getUserCommissionDetailByTimeType(startCalendar.getTime(), endCalendar.getTime(), superiorId);
        } else {
            list = userCommissionMapper.getUserCommissionDetailByTimeType(null, null, superiorId);
        }

        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<IncomeTimeVO> getUserCommissionChange(User user) {
        Long superiorId = user.getId();
        List<Byte> types = new ArrayList<>();
        types.add(UserCommissionTypeEnum.MEMBER_SHARE_COMMISSION.getType());
        types.add(UserCommissionTypeEnum.PARTNER_SHARE_COMMISSION.getType());
        types.add(UserCommissionTypeEnum.SHAREHOLDER_SHARE_COMMISSION.getType());
        IncomeTimeVO incomeTime = userCommissionMapper.getIncomeTime(superiorId, types);
        return new ResultData<>(incomeTime);
    }

    @Override
    public ResultData<List<RankNicknamePerformanceVO>> getRankByType(TimeTypeReq req) {

        //获取传入的日期
        Calendar startCalendar = Calendar.getInstance();
        Calendar endCalendar = Calendar.getInstance();
        Date date = req.getDate();
        Byte timeType = req.getTimeType();
        if (date == null) {
            date = new Date();
        }
        startCalendar.setTime(date);
        endCalendar.setTime(date);
        if (TimeType.DAY.getType().equals(timeType)) {
            //本日明细
            getFirstTime(startCalendar);
            endCalendar.add(Calendar.DATE, +1);
            getFirstTime(endCalendar);
        } else if (TimeType.WEEK.getType().equals(timeType)) {

            // 如果今天是周日，则减一天，才会显示当周
            if (startCalendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
                startCalendar.add(Calendar.DATE, -1);
                endCalendar.add(Calendar.DATE, -1);
            }

            //本周明细
            getFirstTime(startCalendar);
            startCalendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            getFirstTime(endCalendar);
            endCalendar.add(Calendar.WEEK_OF_YEAR, +1);
            endCalendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            getFirstTime(endCalendar);
        } else if (TimeType.MONTH.getType().equals(timeType)) {
            //本月明细
            getFirstTime(startCalendar);
            startCalendar.set(Calendar.DAY_OF_MONTH, 1);
            getFirstTime(endCalendar);
            endCalendar.add(Calendar.MONTH, +1);
            endCalendar.set(Calendar.DAY_OF_MONTH, 1);
        }

        List<RankNicknamePerformanceVO> list = userCommissionMapper.getCommissionRankByType(startCalendar.getTime(), endCalendar.getTime());
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, User> userMap = daoService.getUserMap(list.stream().map(RankNicknamePerformanceVO::getUserId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setNickname(userMap.get(item.getUserId()).getNickname());
                item.setAvatar(userMap.get(item.getUserId()).getAvatar());
            });
        }
        return new ResultData<>(list);
    }

    @Override
    public ResultData<List<RankNicknamePerformanceVO>> getChampionByRankType(Byte identityType) {
        Calendar startCalendar = Calendar.getInstance();
        Calendar endCalendar = Calendar.getInstance();
        startCalendar.setTime(new Date());
        endCalendar.setTime(new Date());

        List<RankNicknamePerformanceVO> list = new ArrayList<>();
        //按月排行
        RankNicknamePerformanceVO rankNicknamePerformanceVOMonth = userCommissionMapper.getChampionByRankType(identityType, getFirstTimeByTimeType(startCalendar, TimeType.MONTH.getType()), getEndTimeByTimeType(endCalendar, TimeType.MONTH.getType()));
        if (rankNicknamePerformanceVOMonth != null) {
            rankNicknamePerformanceVOMonth.setNickname(userMapper.findOneById(rankNicknamePerformanceVOMonth.getUserId()).getNickname());
            rankNicknamePerformanceVOMonth.setRankType(RankTypeEnum.MONTH.getRankType());
            list.add(rankNicknamePerformanceVOMonth);
        }
        return new ResultData<>(list);
    }

    /**
     * 此接口作废
     *
     * @param identityType
     * @return
     */
    @Override
    public ResultData<List<RankNicknamePerformanceVO>> getUserCommissionRank(Byte identityType) {
        List<RankNicknamePerformanceVO> list = userCommissionMapper.getUserCommissionRank(identityType);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, User> userMap = daoService.getUserMap(list.stream().map(RankNicknamePerformanceVO::getUserId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setNickname(userMap.get(item.getUserId()).getNickname());
            });
        }
        return new ResultData<>(list);
    }


    @Override
    public ResultData<UserAgentCommissionTotalVO> getTotalUserAgentCommission(User user, Byte type) {
        UserAgentCommissionTotalVO userAgentCommissionTotalVO = agentCommissionMapper.getAgentCommissionByType(user.getId(), type);
        if (userAgentCommissionTotalVO != null) {
            UserAgentLevel selectUserAgentLevel = userAgentLevelMapper.findOneByIdAndTypeAndExpireTime(user.getId(), type, new Date());
            if (selectUserAgentLevel != null) {
                userAgentCommissionTotalVO.setAgentUserName(selectUserAgentLevel.getMergerName());
            }
        }
        return new ResultData<>(userAgentCommissionTotalVO);
    }

    @Override
    public ResultData<BasePageResp<AgentCommissionTotalVO>> getAgentCommissionDetailByTimeType(AgentCommissionDetailReq req) {
        Page page = new Page();
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        req.setUserId(user.getId());
        if (req.getDate() != null) {
            Calendar startCalendar = Calendar.getInstance();
            Calendar endCalendar = Calendar.getInstance();
            startCalendar.setTime(req.getDate());
            endCalendar.setTime(req.getDate());
            if (req.getTimeType() != null) {
                req.setStartTime(getFirstTimeByTimeType(startCalendar, req.getTimeType()));
                req.setEndTime(getEndTimeByTimeType(endCalendar, req.getTimeType()));
            }

        }
        List<AgentCommissionTotalVO> list = new ArrayList<>();
        AgentCommissionTotalVO agentCommissionTotalVO = agentCommissionMapper.getAgentCommissionTotal(req);
        if (agentCommissionTotalVO != null) {
            BigDecimal commissionSum = agentCommissionTotalVO.getTotalCommission();
            Integer countSum = agentCommissionTotalVO.getTotalCount();
            page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
            list = agentCommissionMapper.getAgentCommissionDetail(req);
            list.stream().forEach(item -> {
                item.setCountSum(countSum);
                item.setCommissionSum(commissionSum);
            });
        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<List<IncomeStatisticVo>> getIncomeStatistics(IncomeStatisticReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Long shopId = getUserShopId(user);
        Byte timeType = req.getTimeType();
        Calendar startCalendar = Calendar.getInstance();
        Calendar endCalendar = Calendar.getInstance();
        if (req.getNow() == null) {
            startCalendar.setTime(new Date());
            endCalendar.setTime(new Date());
        } else {
            startCalendar.setTime(req.getNow());
            endCalendar.setTime(req.getNow());
        }

        List<IncomeStatisticVo> list = new ArrayList<>();
        if (TimeType.DAY.getType().equals(timeType)) {
            //本日明细
            startCalendar = getFirstTime(startCalendar);
            endCalendar.add(Calendar.DATE, +1);
            endCalendar = getFirstTime(endCalendar);
            list = orderSkuMapper.getIncomeStatistics(shopId, getFirstTime(startCalendar).getTime(), getFirstTime(endCalendar).getTime());
        } else if (TimeType.WEEK.getType().equals(timeType)) {
            //本周明细
            startCalendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            endCalendar.add(Calendar.WEEK_OF_YEAR, +1);
            endCalendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            list = orderSkuMapper.getIncomeStatistics(shopId, getFirstTime(startCalendar).getTime(), getFirstTime(endCalendar).getTime());
        } else if (TimeType.MONTH.getType().equals(timeType)) {
            //本月明细
            startCalendar = getFirstTime(startCalendar);
            startCalendar.set(Calendar.DAY_OF_MONTH, 1);
            endCalendar = getFirstTime(endCalendar);
            endCalendar.add(Calendar.MONTH, +1);
            endCalendar.set(Calendar.DAY_OF_MONTH, 1);
            list = orderSkuMapper.getIncomeStatistics(shopId, getFirstTime(startCalendar).getTime(), getFirstTime(endCalendar).getTime());
        } else if (TimeType.YEAR.getType().equals(timeType)) {
            //本年明细
            startCalendar = getFirstTime(startCalendar);
            startCalendar.set(Calendar.DAY_OF_YEAR, startCalendar.getActualMinimum(Calendar.DAY_OF_YEAR));
            endCalendar = getFirstTime(endCalendar);
            endCalendar.add(Calendar.YEAR, +1);
            endCalendar.set(Calendar.DAY_OF_YEAR, endCalendar.getActualMinimum(Calendar.DAY_OF_YEAR));
            list = orderSkuMapper.getIncomeStatistics(shopId, getFirstTime(startCalendar).getTime(), getFirstTime(endCalendar).getTime());
        } else {
            list = orderSkuMapper.getIncomeStatistics(shopId, null, null);
        }

        return new ResultData<>(list);
    }


    @Override
    public ResultData<List<IncomeStatisticVo>> getIncomeStatisticsMonth(User user) {
        Long shopId = getUserShopId(user);
        List<IncomeStatisticVo> list = new ArrayList<>();
        if (shopId != null && shopId > 0) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.add(Calendar.MONTH, -6);
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            list = orderSkuMapper.getIncomeStatisticsByType(getFirstTime(calendar).getTime(), shopId);
        }
        return new ResultData<>(list);
    }

    @Override
    public ResultData<List<OrderStatisticVO>> getOrderStatistics(User user, Byte timeType) {
        Long shopId = getUserShopId(user);
        List<OrderStatisticVO> list = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        if (TimeType.DAY.getType().equals(timeType)) {
            calendar.add(Calendar.DATE, -7);
            list = orderSkuMapper.getOrderStatisticsByType(getFirstTime(calendar).getTime(), shopId, timeType);
        }
        if (TimeType.WEEK.getType().equals(timeType)) {
            calendar.add(Calendar.WEEK_OF_YEAR, -7);
            calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            list = orderSkuMapper.getOrderStatisticsByType(getFirstTime(calendar).getTime(), shopId, timeType);
        }
        if (TimeType.MONTH.getType().equals(timeType)) {
            calendar.add(Calendar.MONTH, -7);
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            list = orderSkuMapper.getOrderStatisticsByType(getFirstTime(calendar).getTime(), shopId, timeType);
        }
        if (TimeType.YEAR.getType().equals(timeType)) {
            calendar.add(Calendar.YEAR, -7);
            calendar.set(Calendar.DAY_OF_YEAR, calendar.getActualMinimum(Calendar.DAY_OF_YEAR));
            list = orderSkuMapper.getOrderStatisticsByType(getFirstTime(calendar).getTime(), shopId, timeType);
        }
        return new ResultData<>(list);
    }


    @Override
    public ResultData<List<RewardQueueVO>> getRewardQueue(User user) {
        List<RewardQueueVO> list = new ArrayList<>();
        //获取免单用户
        List<RewardQueueVO> rewardQueueFree = rewardQueueMapper.getRewardQueue(ToggleEnum.ON.getStatus(), ToggleEnum.ON.getStatus());


        if (!CollectionUtils.isEmpty(rewardQueueFree)) {
            Map<Long, User> userMap = daoService.getUserMap(rewardQueueFree.stream().map(RewardQueueVO::getUserId).collect(Collectors.toList()));
            List<RewardQueue> updateAudio = new ArrayList<>();
            rewardQueueFree.stream().forEach(item -> {
                try {
                    item.setUserType((byte) 0);
                    //语音文件为空就生成
                    if (item.getAudioUrl() == null) {
                        item.setAudioUrl(baiduService.createAudio(userMap.get(item.getUserId()).getNickname() + "自动免单补贴到账" + item.getAmount() + "元"));
                        updateAudio.add(RewardQueue.builder().id(item.getId()).audioUrl(item.getAudioUrl()).build());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });

            //更新免单语音链接
            if (!CollectionUtils.isEmpty(updateAudio)) {
                rewardQueueMapper.updateBatchAudioUrl(updateAudio);
            }
            list.addAll(rewardQueueFree);
        }
        //获取购买用户
        List<RewardQueueVO> rewardQueueBuy = rewardQueueMapper.getRewardQueue(ToggleEnum.OFF.getStatus(), ToggleEnum.OFF.getStatus());
        rewardQueueBuy.stream().forEach(item -> {
            item.setUserType((byte) 1);
        });
        //语音播报是否开启
        Byte isVoiceOn = 1;
        if (user != null) {
            VoiceSet selectVoiceSet = voiceSetMapper.findOneByUserId(user.getId());
            if (selectVoiceSet == null) {
                VoiceSet voiceSet = VoiceSet.builder().userId(user.getId()).type(ToggleEnum.ON.getStatus()).build();
                voiceSetMapper.insert(voiceSet);
                isVoiceOn = voiceSet.getType();
            } else {
                isVoiceOn = selectVoiceSet.getType();
            }
        }


        list.addAll(rewardQueueBuy);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, User> userMap = daoService.getUserMap(list.stream().map(RewardQueueVO::getUserId).collect(Collectors.toList()));
            Map<Long, Spu> spuMap = daoService.getSpuMap(list.stream().map(RewardQueueVO::getSpuId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setUserNickname(userMap.get(item.getUserId()).getNickname());
                item.setUserAvatar(userMap.get(item.getUserId()).getAvatar());
                if (!CollectionUtils.isEmpty(spuMap)) {
                    item.setSpuName(spuMap.get(item.getSpuId()).getName());
                }
            });
        }
        for (int i = 0; i < list.size(); i++) {
            list.get(i).setIsVoiceOn(isVoiceOn);
        }

        return new ResultData<>(list);
    }

    @Override
    public ResultData<BasePageResp<RewardQueueVO>> getMyRewardQueuePage(User user, RewardQueuePageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        req.setUserId(user.getId());
        List<RewardQueueVO> list = rewardQueueMapper.findAllRewardPage(req);
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public BaseResp editVoiceSet(User user) {
        VoiceSet selectVoiceSet = voiceSetMapper.findOneByUserId(user.getId());
        if (ToggleEnum.ON.getStatus().equals(selectVoiceSet.getType())) {
            voiceSetMapper.updateTypeByUserId(ToggleEnum.OFF.getStatus(), user.getId());
        }
        if (ToggleEnum.OFF.getStatus().equals(selectVoiceSet.getType())) {
            voiceSetMapper.updateTypeByUserId(ToggleEnum.ON.getStatus(), user.getId());
        }
        return new BaseResp();
    }

    @Override
    public ResultData<RewardQueue> getLastRewardQueueAudio(User user) {
        RewardQueue rewardQueue = rewardQueueMapper.findOneTopReward(ToggleEnum.ON.getStatus());
        if (rewardQueue != null) {
            if (rewardQueue.getAudioUrl() == null) {
                // 生成语音URL
                try {
                    // 获取昵称
                    User result = userMapper.selectByPrimaryKey(rewardQueue.getUserId());
                    String url = baiduService.createAudio(result.getNickname() + "自动免单补贴到账" + rewardQueue.getAmount() + "元");
                    rewardQueue.setAudioUrl(url);
                    rewardQueueMapper.updateByPrimaryKeySelective(rewardQueue);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            // 判断是否已读
            AudioListen audioListen = audioListenMapper.findOneByUserIdAndRewardQueueId(user.getId(), rewardQueue.getId());
            if (audioListen == null && rewardQueue.getAudioUrl() != null) {
                // 改成已读
                audioListenMapper.insert(AudioListen.builder().userId(user.getId()).rewardQueueId(rewardQueue.getId()).createdAt(new Date()).build());
                return new ResultData<>(rewardQueue);
            }
        }
        return new ResultData<>(null);
    }

    @Override
    public ResultData<List<UserGroupCommissionVO>> getUserGroupByIdentityType(Byte identityType) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Long captainId = user.getId();
        List<UserGroupCommissionVO> list = userGroupMapper.getUserGroupByIdentityType(identityType, captainId);
        return new ResultData<>(list);
    }

    @Override
    public ResultData<BasePageResp<UserGroupListVO>> getUserGroupMemberByMemberType(MemberTypeReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (req.getUserId() != null) {
            UserGroup userGroup = userGroupMapper.findOneByCaptainIdAndMemberId(user.getId(), req.getUserId());
            if (userGroup == null && !req.getUserId().equals(user.getId())) {
                ResultData<BasePageResp<UserGroupListVO>> resultData = new ResultData<>();
                BasePageResp<UserGroupListVO> objectBasePageResp = new BasePageResp<>();
                objectBasePageResp.setData(new ArrayList<>());
                resultData.setValue(objectBasePageResp);
                return resultData;
            }
        } else {
            req.setUserId(user.getId());
        }
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<UserGroupListVO> list = userGroupMapper.getUserGroupMemberByMemberType(req);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, User> userMap = daoService.getUserMap(list.stream().map(UserGroupListVO::getMemberId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setMemberNickname(userMap.get(item.getMemberId()).getNickname());
                item.setMemberAvatar(userMap.get(item.getMemberId()).getAvatar());
            });
        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<UserGroupCaptainDetailVO> getUserGroupCaptainDetail(User user) {
        UserGroupCaptainDetailVO vo = new UserGroupCaptainDetailVO();
        UserRelationship userRelationship = userRelationshipMapper.findOneBySubordinateIdAndStatus(user.getId(), RelationshipStatusEnum.BIND.getStatus());
        if (userRelationship != null) {
            User superior = userMapper.selectByPrimaryKey(userRelationship.getSuperiorId());
            vo.setSuperiorNickname(superior.getNickname());
            vo.setSuperiorId(superior.getId());
        }
        vo.setMemberNumber(userGroupMapper.getCaptainGroupMemberNumber(user.getId()).getUserGroupNumber());
        return new ResultData<>(vo);
    }

    @Override
    public ResultData<BusinessCardVO> getUserGroupMemberBusinessCard(Long userId) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        BusinessCardVO vo = new BusinessCardVO();
        //当前团员是登陆用户的团员
        if (userGroupMapper.selectOneByMemberId(userId).getCaptainId().equals(user.getId())) {
            vo = businessCardMapper.findOneByUserId(userId);
            User selectUser = userMapper.selectByPrimaryKey(userId);
            vo.setAvatar(selectUser.getAvatar());
            vo.setNickname(selectUser.getNickname());
            vo.setUsername(selectUser.getUsername());
            return new ResultData<>(vo);
        }
        return new ResultData<>();
    }

    @Override
    public ResultData<Identity> getUserPromotionIdentity(User user) {
        Identity identity = identityMapper.selectOneByUserId(user.getId());
        return new ResultData<>(identity);
    }

    @Override
    public ResultData<List<UserDirectPushStatisticsVO>> getUserDirectPushNumberStatistics(User user) {
        Long superiorId = user.getId();
        List<UserDirectPushStatisticsVO> list = userRelationshipMapper.getUserDirectPushNumberStatistics(superiorId);
        return new ResultData<>(list);
    }

    @Override
    public ResultData<List<PromotionIncomeAndTotalAmountVO>> getPromotionIncomeAndTotalAmount(User user) {
        List<PromotionIncomeAndTotalAmountVO> voList = new ArrayList<>();
        List<Byte> partnerBytes = new ArrayList<>();
        partnerBytes.add(UserCommissionTypeEnum.PARTNER_L2_DIVIDENDS.getType());
        partnerBytes.add(UserCommissionTypeEnum.PARTNER_L3_DIVIDENDS.getType());
        partnerBytes.add(UserCommissionTypeEnum.PARTNER_L4_DIVIDENDS.getType());
        getPromotionCommon(user.getId(), partnerBytes, voList);
        List<Byte> MemberBytes = new ArrayList<>();
        MemberBytes.add(UserCommissionTypeEnum.MEMBER_L2_DIVIDENDS.getType());
        MemberBytes.add(UserCommissionTypeEnum.MEMBER_L3_DIVIDENDS.getType());
        MemberBytes.add(UserCommissionTypeEnum.MEMBER_L4_DIVIDENDS.getType());
        getPromotionCommon(user.getId(), MemberBytes, voList);
        return new ResultData<>(voList);
    }

    private void getPromotionCommon(Long id, List<Byte> bytes, List<PromotionIncomeAndTotalAmountVO> list) {
        BigDecimal partnerPromotion = userCommissionMapper.getPromotionIncomeByType(id, bytes);
        PromotionIncomeAndTotalAmountVO vo = new PromotionIncomeAndTotalAmountVO();
        vo.setPromotionIncome(partnerPromotion);
        BigDecimal totalAmount = userCommissionMapper.getTotalAmountByType(bytes);
        vo.setTotalAmount(totalAmount);
        vo.setPromotionType(bytes.contains(UserCommissionTypeEnum.MEMBER_L2_DIVIDENDS.getType()) ? (byte) 0 : (byte) 1);
        list.add(vo);
    }

    @Override
    public ResultData<List<PromotionIncomeStatisticsVO>> getPromotionIncomeStatistics(User user) {
        Calendar startCalendar = Calendar.getInstance();
        Calendar endCalendar = Calendar.getInstance();
        startCalendar.setTime(new Date());
        endCalendar.setTime(new Date());
        List<PromotionIncomeStatisticsVO> list = userCommissionMapper.getPromotionIncomeStatistics(getFirstTimeByTimeType(startCalendar, TimeType.MONTH.getType()), getEndTimeByTimeType(endCalendar, TimeType.MONTH.getType()), user.getId());
        return new ResultData<>(list);
    }

    @Override
    public ResultData<List<HipoConfig>> getPromotionIdentityValue(User user) {
        List<String> list = new ArrayList<>();
        list.add(HipoConfigEnum.PARTNER_DIVIDENDS_1_RATE.getConfig());
        list.add(HipoConfigEnum.PARTNER_DIVIDENDS_2_RATE.getConfig());
        list.add(HipoConfigEnum.PARTNER_DIVIDENDS_3_RATE.getConfig());
        list.add(HipoConfigEnum.MEMBER_DIVIDENDS_1_RATE.getConfig());
        list.add(HipoConfigEnum.MEMBER_DIVIDENDS_2_RATE.getConfig());
        list.add(HipoConfigEnum.MEMBER_DIVIDENDS_3_RATE.getConfig());
        list.add(HipoConfigEnum.SHAREHOLDER_DIVIDENDS_1_RATE.getConfig());
        list.add(HipoConfigEnum.SHAREHOLDER_DIVIDENDS_2_RATE.getConfig());
        list.add(HipoConfigEnum.SHAREHOLDER_DIVIDENDS_3_RATE.getConfig());
        List<HipoConfig> hipoConfigList = hipoConfigMapper.selectAllByNameList(list);
        return new ResultData<>(hipoConfigList);
    }

    @Override
    public ResultData<List<AvgPromotionIncomeVO>> getAvgPromotionIncome(User user) {
        //合伙人分红
        List<AvgPromotionIncomeVO> list = identityMapper.getNumberByPartnerLevel(new Date());
        List<Byte> bytes = new ArrayList<>();
        bytes.add(UserCommissionTypeEnum.PARTNER_L2_DIVIDENDS.getType());
        bytes.add(UserCommissionTypeEnum.PARTNER_L3_DIVIDENDS.getType());
        bytes.add(UserCommissionTypeEnum.PARTNER_L4_DIVIDENDS.getType());
        commonPromotionIncome(list, bytes);

        //会员分红
        List<AvgPromotionIncomeVO> memberList = identityMapper.getNumberByMemberLevel(new Date());
        List<Byte> memberBytes = new ArrayList<>();
        memberBytes.add(UserCommissionTypeEnum.MEMBER_L2_DIVIDENDS.getType());
        memberBytes.add(UserCommissionTypeEnum.MEMBER_L3_DIVIDENDS.getType());
        memberBytes.add(UserCommissionTypeEnum.MEMBER_L4_DIVIDENDS.getType());
        commonPromotionIncome(memberList, memberBytes);

        //运营中心分红
        List<AvgPromotionIncomeVO> shareholderList = identityMapper.getNumberByShareholderListLevel();
        List<Byte> shareholderBytes = new ArrayList<>();
        shareholderBytes.add(UserCommissionTypeEnum.SHAREHOLDER_L2_DIVIDENDS.getType());
        shareholderBytes.add(UserCommissionTypeEnum.SHAREHOLDER_L3_DIVIDENDS.getType());
        shareholderBytes.add(UserCommissionTypeEnum.SHAREHOLDER_L4_DIVIDENDS.getType());
        commonPromotionIncome(shareholderList, shareholderBytes);

        list.addAll(memberList);
        list.addAll(shareholderList);
        return new ResultData<>(list);
    }

    private void commonPromotionIncome(List<AvgPromotionIncomeVO> list, List<Byte> bytes) {
        Long totalCount = userCommissionMapper.countByTypeIn(bytes);
        if (!CollectionUtils.isEmpty(list)) {
            List<AvgPromotionIncomeVO> avgPromotionIncomes = userCommissionMapper.getAllAvgPromotionIncome(bytes);
            Map<Byte, AvgPromotionIncomeVO> avgPromotionIncomeVOMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(avgPromotionIncomes)) {
                avgPromotionIncomes.stream().forEach(item -> {
                    avgPromotionIncomeVOMap.put(item.getIncomeIdentityType(), item);
                });
            }
            list.stream().forEach(item -> {
                Byte type = BonusCommissionEnum.getType(item.getLevel());
                AvgPromotionIncomeVO avgPromotionIncomeVO = avgPromotionIncomeVOMap.get(type);
                if (avgPromotionIncomeVO != null) {
                    item.setTotalIncome(avgPromotionIncomeVO.getTotalIncome());
                    item.setAmount(avgPromotionIncomeVO.getAmount());
                    item.setIncomeIdentityType(type);
                }
                if (item.getNumber() != 0 && item.getTotalIncome() != null) {
                    item.setAvgIncome(item.getTotalIncome().divide(new BigDecimal(item.getNumber().toString()), 2, BigDecimal.ROUND_HALF_UP));
                }
                item.setTotalCount(totalCount);
            });
        }

        //添加空数据
        if (list == null || list.size() < 3) {
            List<Byte> collect = list.stream().map(AvgPromotionIncomeVO::getIncomeIdentityType).collect(Collectors.toList());
            bytes.stream().forEach(item -> {
                if (!collect.contains(item)) {
                    AvgPromotionIncomeVO newVo = new AvgPromotionIncomeVO();
                    newVo.setIncomeIdentityType(item);
                    newVo.setLevel(BonusCommissionEnum.getLevel(item));
                    list.add(newVo);
                }
            });
        }
    }


    @Override
    public ResultData<List<IncomeTimeVO>> getPromotionIncomeChange(User user) {
        List<IncomeTimeVO> voList = new ArrayList<>();
        List<Byte> partnerTypes = new ArrayList<>();
        partnerTypes.add(UserCommissionTypeEnum.PARTNER_L2_DIVIDENDS.getType());
        partnerTypes.add(UserCommissionTypeEnum.PARTNER_L3_DIVIDENDS.getType());
        partnerTypes.add(UserCommissionTypeEnum.PARTNER_L4_DIVIDENDS.getType());
        IncomeTimeVO partnerIncome = userCommissionMapper.getIncomeTime(user.getId(), partnerTypes);
        if (partnerIncome == null) {
            partnerIncome = new IncomeTimeVO();
        }
        partnerIncome.setType(IdentityTypeEnum.PARTNER.getType());
        voList.add(partnerIncome);

        List<Byte> memberTypes = new ArrayList<>();
        memberTypes.add(UserCommissionTypeEnum.MEMBER_L2_DIVIDENDS.getType());
        memberTypes.add(UserCommissionTypeEnum.MEMBER_L3_DIVIDENDS.getType());
        memberTypes.add(UserCommissionTypeEnum.MEMBER_L4_DIVIDENDS.getType());
        IncomeTimeVO memberIncome = userCommissionMapper.getIncomeTime(user.getId(), memberTypes);
        if (memberIncome == null) {
            memberIncome = new IncomeTimeVO();
        }
        memberIncome.setType(IdentityTypeEnum.MEMBER.getType());
        voList.add(memberIncome);
        return new ResultData<>(voList);
    }

    @Override
    public ResultData<PromotionAwardDetailVO> getPromotionAwardDetail(User user, Byte type) {
        Integer userLevel;
        Integer totalOrderAmount;
        Byte userCommissionType;
        Long bonusCount;
        if (IdentityTypeEnum.MEMBER.getType().equals(type)) {
            userLevel = UserLevelEnum.MEMBER_L4.getLevel();
            totalOrderAmount = identityMapper.getTotalMemberOrderAmount(UserLevelEnum.CUSTOMER.getLevel());
            userCommissionType = UserCommissionTypeEnum.MEMBER_L4_BONUS.getType();
            bonusCount = bonusCountMapper.findOneByRewardType(RewardTypeEnum.MEMBER_L4.getType()).getCount();
        } else if (IdentityTypeEnum.PARTNER.getType().equals(type)) {
            userLevel = UserLevelEnum.PARTNER_L4.getLevel();
            totalOrderAmount = identityMapper.getTotalPartnerOrderAmount(UserLevelEnum.CUSTOMER.getLevel());
            userCommissionType = UserCommissionTypeEnum.PARTNER_L4_BONUS.getType();
            bonusCount = bonusCountMapper.findOneByRewardType(RewardTypeEnum.PARTNER_L4.getType()).getCount();
        } else {
            userLevel = UserLevelEnum.SHAREHOLDER_L4.getLevel();
            totalOrderAmount = identityMapper.getTotalShareholderOrderAmount(UserLevelEnum.CUSTOMER.getLevel());
            userCommissionType = UserCommissionTypeEnum.SHAREHOLDER_L4_BONUS.getType();
            bonusCount = bonusCountMapper.findOneByRewardType(RewardTypeEnum.SHAREHOLDER_L4.getType()).getCount();
        }
        PromotionAwardDetailVO vo = new PromotionAwardDetailVO();
        Long superiorId = user.getId();
        //查询当前用户晋级主席奖励总和
        BigDecimal awardIncome = userCommissionMapper.getIncomeByType(superiorId, userCommissionType);

        vo.setAwardIncome(awardIncome == null ? new BigDecimal(BigInteger.ZERO) : awardIncome);
        vo.setBonusCount(bonusCount);
        //获取xxx_level > 0的人作为全国总订单数
        vo.setTotalOrderAmount(totalOrderAmount);
        //获取最早的那条订单在reward_queue队列前面多少人+1作为队列位置
        Date date = rewardQueueMapper.getEarliestRewardQueue(superiorId, RewardQueueTypeEnum.NORMAL.getType(), userLevel, RewardQueueStatusEnum.QUEUING.getStatus());
        if (date == null) {
            Integer queueNumber = rewardQueueMapper.getAwardIncomeQueueNumber(date, RewardQueueTypeEnum.NORMAL.getType(), userLevel, RewardQueueStatusEnum.QUEUING.getStatus());
            vo.setQueueNumber(queueNumber == null ? 1 : queueNumber + 1);
        }

        return new ResultData<>(vo);
    }

    @Override
    public ResultData<List<HistoryAwardVO>> getHistoryAward(User user, Byte type) {
        Integer userLevel;
        if (IdentityTypeEnum.MEMBER.getType().equals(type)) {
            userLevel = UserLevelEnum.MEMBER_L4.getLevel();
        } else if (IdentityTypeEnum.PARTNER.getType().equals(type)) {
            userLevel = UserLevelEnum.PARTNER_L4.getLevel();
        } else {
            userLevel = UserLevelEnum.SHAREHOLDER_L4.getLevel();
        }
        //获取历史奖励（非免单商品，用户等级为主席，奖励已领取）
        List<HistoryAwardVO> list = rewardQueueMapper.getHistoryAward(RewardQueueTypeEnum.NORMAL.getType(), userLevel, ToggleEnum.ON.getStatus());
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, User> userMap = daoService.getUserMap(list.stream().map(HistoryAwardVO::getUserId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setUserNickname(userMap.get(item.getUserId()).getNickname());
            });
        }
        return new ResultData<>(list);
    }

    @Override
    public ResultData<List<RewardQueueLatelyVO>> getRewardQueueLately(User user, Byte type) {
        Integer userLevel;
        if (IdentityTypeEnum.MEMBER.getType().equals(type)) {
            userLevel = UserLevelEnum.MEMBER_L4.getLevel();
        } else if (IdentityTypeEnum.PARTNER.getType().equals(type)) {
            userLevel = UserLevelEnum.PARTNER_L4.getLevel();
        } else {
            userLevel = UserLevelEnum.SHAREHOLDER_L4.getLevel();
        }
        List<RewardQueueLatelyVO> list = rewardQueueMapper.getRewardQueueLately(RewardQueueTypeEnum.NORMAL.getType(), userLevel);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, User> userMap = daoService.getUserMap(list.stream().map(RewardQueueLatelyVO::getUserId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                if (userMap.get(item.getId()) != null) {
                    item.setUserNickname(userMap.get(item.getUserId()).getNickname());
                }
            });
        }
        return new ResultData<>(list);
    }

    @Override
    public BaseResp addShopCollection(ShopCollection shopCollection) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Shop shop = shopMapper.selectByPrimaryKey(shopCollection.getShopId());
        if (shop != null) {
            shopCollection.setUserId(user.getId());
            shopCollection.setCreatedAt(new Date());
            shopCollection.setShopName(shop.getShopName());
            shopCollectionMapper.insert(shopCollection);
        }
        return new BaseResp();
    }

    @Override
    public BaseResp deleteShopCollection(Long shopId) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        ShopCollection selectShopCollection = shopCollectionMapper.findOneByShopIdAndUserId(shopId, user.getId());
        if (selectShopCollection != null) {
            shopCollectionMapper.deleteByPrimaryKey(selectShopCollection.getId());
        }
        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<ShopCollectionVO>> getShopCollectionPage(PageReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        req.setUserId(user.getId());
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<ShopCollectionVO> list = shopCollectionMapper.findAllPage(req);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, Shop> shopMap = daoService.getShopMap(list.stream().map(ShopCollectionVO::getShopId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                if (shopMap.get(item.getShopId()) != null) {
                    item.setShopName(shopMap.get(item.getShopId()).getShopName());
                    item.setShopAvatar(shopMap.get(item.getShopId()).getAvatar());
                    item.setShopType(shopMap.get(item.getShopId()).getType());
                }
            });
        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<CardFlowStatisticsVO> getCardFlowStatistics(TimeTypeReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (req.getTimeType() == null) {
            req.setTimeType(TimeType.YEAR.getType());
        }
        Byte timeType = req.getTimeType();
        Calendar calendar = Calendar.getInstance();
        Calendar endCalendar = Calendar.getInstance();
        if (req.getDate() == null) {
            calendar.setTime(new Date());
            endCalendar.setTime(new Date());
        } else {
            calendar.setTime(req.getDate());
            endCalendar.setTime(req.getDate());
        }
        req.setUserId(user.getId());
        TotalStatisticsVO totalStatisticsVO = new TotalStatisticsVO();
        CardFlowStatisticsVO vo = new CardFlowStatisticsVO();
        List<StatisticsVO> statisticsVOList = new ArrayList<>();
        if (timeType.equals(TimeType.DAY.getType())) {
            //近6日
            calendar.add(Calendar.DATE, -5);
            endCalendar.add(Calendar.DATE, +1);
        } else if (timeType.equals(TimeType.WEEK.getType())) {
            //近6周
            calendar.add(Calendar.WEEK_OF_YEAR, -5);
            calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            endCalendar.add(Calendar.WEEK_OF_YEAR, +1);
            endCalendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);

        } else if (timeType.equals(TimeType.MONTH.getType())) {
            //近6月
            calendar.add(Calendar.MONTH, -5);
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            endCalendar.add(Calendar.MONTH, +1);
            endCalendar.set(Calendar.DAY_OF_MONTH, 1);

        } else {
            //近6年
            calendar.add(Calendar.YEAR, -5);
            calendar.set(Calendar.DAY_OF_YEAR, calendar.getActualMinimum(Calendar.DAY_OF_YEAR));
            endCalendar.add(Calendar.YEAR, +1);
            endCalendar.set(Calendar.DAY_OF_YEAR, calendar.getActualMinimum(Calendar.DAY_OF_YEAR));
        }
        req.setStartTime(getFirstTime(calendar).getTime());
        req.setEndTime(getFirstTime(endCalendar).getTime());
        totalStatisticsVO = cardFlowMapper.getTotalCardFlow(req);
        statisticsVOList = cardFlowMapper.getCardFlowStatistics(req);
        vo.setTotalStatisticsVO(totalStatisticsVO);
        vo.setStatisticsVOList(statisticsVOList);
        return new ResultData<>(vo);
    }

    @Override
    public ResultData<List<CardFlow>> getCardFlowRecordRank(TimeTypeReq req) {
        List<CardFlow> list = new ArrayList<>();
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Byte timeType = req.getTimeType();
        Calendar calendar = Calendar.getInstance();
        Calendar endCalendar = Calendar.getInstance();
        if (req.getDate() == null) {
            calendar.setTime(new Date());
            endCalendar.setTime(new Date());
        } else {
            calendar.setTime(req.getDate());
            endCalendar.setTime(req.getDate());
        }
        req.setUserId(user.getId());
        if (TimeType.DAY.getType().equals(timeType)) {
            //近6日
            calendar.add(Calendar.DATE, -5);
            endCalendar.add(Calendar.DATE, +1);
        } else if (TimeType.WEEK.getType().equals(timeType)) {
            //近6周
            calendar.add(Calendar.WEEK_OF_YEAR, -5);
            calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            endCalendar.add(Calendar.WEEK_OF_YEAR, +1);
            endCalendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);

        } else if (TimeType.MONTH.getType().equals(timeType)) {
            //近6月
            calendar.add(Calendar.MONTH, -5);
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            endCalendar.add(Calendar.MONTH, +1);
            endCalendar.set(Calendar.DAY_OF_MONTH, 1);

        } else {
            //近6年
            calendar.add(Calendar.YEAR, -5);
            calendar.set(Calendar.DAY_OF_YEAR, calendar.getActualMinimum(Calendar.DAY_OF_YEAR));
            endCalendar.add(Calendar.YEAR, +1);
            endCalendar.set(Calendar.DAY_OF_YEAR, calendar.getActualMinimum(Calendar.DAY_OF_YEAR));
        }
        req.setStartTime(getFirstTime(calendar).getTime());
        req.setEndTime(getFirstTime(endCalendar).getTime());
        list = cardFlowMapper.getCardFlowRecordRank(req);
        return new ResultData<>(list);
    }

    @Override
    public ResultData<List<StatisticsVO>> getCardFlowCurrentMonth(Byte type) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, -5);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        List<StatisticsVO> list = cardFlowMapper.getCardFlowCurrentMonth(user.getId(), type, calendar.getTime());
        return new ResultData<>(list);
    }

    @Override
    public ResultData<List<CommissionByTypeVO>> getMyCommission(User user) {
        List<CommissionByTypeVO> list = userCommissionMapper.getMyCommission(user.getId());
        return new ResultData<>(list);
    }

    @Override
    public ResultData<RecommendShopVO> getRecommendShop(User user) {
        RecommendShopVO vo = new RecommendShopVO();
        vo.setRecommendShopIncome(userCommissionMapper.getIncomeByType(user.getId(), UserCommissionTypeEnum.SHOP_RECOMMEND_BONUS.getType()));
        vo.setRecommendShopNumber(shopRelationshipMapper.getRecommendShopNumber(user.getId()));
        vo.setRecommendShopAmount(userCommissionMapper.getAmountByType(user.getId(), UserCommissionTypeEnum.SHOP_RECOMMEND_BONUS.getType()));
        vo.setRecommendShopReward(userCommissionMapper.getIncomeByType(user.getId(), UserCommissionTypeEnum.SHOP_RECOMMEND_BONUS.getType()));
        return new ResultData<>(vo);
    }

    @Override
    public ResultData<List<MyDirectPushShopVO>> getMyDirectPushShopList(User user) {
        List<MyDirectPushShopVO> list = userCommissionMapper.getMyDirectPushShopList(user.getId(), UserCommissionTypeEnum.SHOP_RECOMMEND_BONUS.getType());
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, Shop> shopMap = daoService.getShopMap(list.stream().map(MyDirectPushShopVO::getShopId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setShopName(shopMap.get(item.getShopId()).getShopName());
            });
        }
        return new ResultData<>(list);
    }

    @Override
    public ResultData<FreeOrderMoneyVO> getFreeOrderMoney(User user, Byte rewardType) {
        if (rewardType == null) {
            rewardType = RewardTypeEnum.MEMBER_INVITE.getType();
        }
        BigDecimal freeOrderMoney = rewardQueueMapper.getFreeOrderMoney(user.getId(), rewardType);
        BigDecimal noFreeOrderMoney = rewardQueueMapper.getNoFreeOrderMoney(user.getId(), rewardType);
        FreeOrderMoneyVO vo = new FreeOrderMoneyVO();
        vo.setFreeOrderMoney(freeOrderMoney);
        vo.setNoFreeOrderMoney(noFreeOrderMoney);
        return new ResultData<>(vo);
    }

    @Override
    public ResultData<BasePageResp<FreeOrderListVO>> getFreeOrderPage(PageReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        req.setUserId(user.getId());
        if (RewardStatusEnum.NO_FREE_ORDER.getType().equals(req.getType())) {
            req.setStatus(RewardQueueStatusEnum.QUEUING.getStatus());
            req.setCommonStatus(RewardReceiveStatusEnum.NO_RECEIVED.getStatus());
        }
        if (RewardStatusEnum.FREE_ORDER.getType().equals(req.getType())) {
            req.setStatus(RewardQueueStatusEnum.QUEUED.getStatus());
            req.setCommonStatus(RewardReceiveStatusEnum.RECEIVED.getStatus());
        }

        List<FreeOrderListVO> list = rewardQueueMapper.getFreeOrderPage(req);
        if (!CollectionUtils.isEmpty(list)) {
            List<Long> spuIds = list.stream().map(FreeOrderListVO::getSpuId).collect(Collectors.toList()).stream().filter(Objects::nonNull).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(spuIds)) {
                Map<Long, Spu> spuMap = daoService.getSpuMap(spuIds);
                Map<Long, Shop> shopMap = daoService.getShopMap(spuMap.values().stream().map(Spu::getTenantId).collect(Collectors.toList()));
                list.stream().forEach(item -> {
                    if (spuMap.get(item.getSpuId()) != null) {
                        item.setSpuName(spuMap.get(item.getSpuId()).getName());
                        item.setShopId(shopMap.get(spuMap.get(item.getSpuId()).getTenantId()).getId());
                        item.setShopName(shopMap.get(spuMap.get(item.getSpuId()).getTenantId()).getShopName());
                    }
                    //是否排队中
//                    if (item.getQueueStatus().equals(RewardQueueStatusEnum.QUEUING.getStatus())) {
//                        Integer currentQueue = null;
//                        if (item.getType().equals(RewardQueueTypeEnum.SPU.getType())) {
//                            currentQueue = rewardQueueMapper.getFreeOrderCurrentQueue(item.getFreeTime(), user.getId(), RewardQueueTypeEnum.SPU.getType(), item.getSpuId()) + 1;
//                        }
//                        if (item.getType().equals(RewardQueueTypeEnum.NORMAL.getType())) {
//                            currentQueue = rewardQueueMapper.getNoFreeOrderCurrentQueue(item.getFreeTime(), user.getId(), RewardQueueTypeEnum.NORMAL.getType(), item.getLevel()) + 1;
//                        }
//                        item.setCurrentQueue(currentQueue);
//                    }
                });
            }
        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<BigDecimal> sumOfCommissionByType(User user, Byte type) {
        return new ResultData<>(userCommissionMapper.sumBySuperiorIdAndType(user.getId(), type));
    }

    @Override
    public ResultData<List<PartnerRankVO>> getPartnerRank(PartnerRankReq req) {
        List<PartnerRankVO> list = new ArrayList<>();
        Calendar startCalendar = Calendar.getInstance();
        Calendar endCalendar = Calendar.getInstance();
        if (req.getTime() == null) {
            startCalendar.setTime(new Date());
            endCalendar.setTime(new Date());
            Date startTime = getFirstTimeByTimeType(startCalendar, req.getRankType());
            Date endTime = getEndTimeByTimeType(endCalendar, req.getRankType());
            list = userCommissionMapper.getPartnerRank(startTime, endTime);
            if (!CollectionUtils.isEmpty(list)) {
                Map<Long, User> userMap = daoService.getUserMap(list.stream().map(PartnerRankVO::getUserId).collect(Collectors.toList()));
                list.stream().forEach(item -> {
                    item.setUserNickname(userMap.get(item.getUserId()).getNickname());
                });
            }
        } else {
            //获取历史排行
            list = rankRecordMapper.findAllByDateAndType(getFirstTime(getSunday(req.getTime())).getTime(), req.getRankType());
        }
        return new ResultData<>(list);
    }

    @Override
    public ResultData<Boolean> isBossOrOwner() {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Shop shop = shopMapper.selectByPrimaryKey(user.getShopId());

        if (shop == null || (!user.getId().equals(shop.getUserId()))) {
            // 如果不是店长，就判断是否是老板
            Boss boss = bossMapper.findOneByShopId(shop.getId());
            if (boss == null || !boss.getUserId().equals(user.getId())) {
                return new ResultData<>(false);
            }
        }
        return new ResultData<>(true);
    }

    private Calendar getSunday(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
        if (1 == dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        int day = cal.get(Calendar.DAY_OF_WEEK);
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
        cal.add(Calendar.DATE, 6);
        return cal;
    }

    @Override
    public ResultData<AreaApplyAreaVO> getAreaApplyList(Long city) {
        AreaApplyAreaVO vo = new AreaApplyAreaVO();
        List<Area> areaList = areaMapper.findAllByParentId(city);
        List<UserAgentLevel> userAgentLevelList = userAgentLevelMapper.findAllByLocationIdsAndExpireTime(areaList.stream().map(Area::getId).collect(Collectors.toList()), new Date());
        List<AreaApplyDetail> exist = new ArrayList<>();
        if (!CollectionUtils.isEmpty(userAgentLevelList)) {
            userAgentLevelList.stream().forEach(item -> {
                exist.add(AreaApplyDetail.builder().userId(item.getUserId()).area(item.getLocationId()).build());
            });
        }
        vo.setExist(exist);
        vo.setApply(areaApplyDetailMapper.findAllByCityAndStatus(city, AreaApplyStatusEnum.WAIT_AUDIT.getStatus()));
        vo.setAreaPrice(new BigDecimal(hipoConfigMapper.findValueByName(HipoConfigEnum.AREA_PRICE.getConfig())));
        return new ResultData<>(vo);
    }

    @Override
    public BaseResp editAreaApply(AreaApplyReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (req.getId() == null) {
            List<AreaReq> areaList = req.getAreaList();

            if (CollectionUtils.isEmpty(areaList)) {
                return new BaseResp(ResultCode.NOT_CHOICE_AREA);
            }

            //判断是否被占用或在申请中
            List<Long> areApplyList = areaList.stream().map(AreaReq::getArea).collect(Collectors.toList());
            List<AreaApplyDetail> waitPassDetail = areaApplyDetailMapper.findAllByAreasAndStatus(areApplyList, AreaApplyStatusEnum.WAIT_AUDIT.getStatus());
            List<UserAgentLevel> existUserAgent = userAgentLevelMapper.findAllByLocationIdsAndExpireTime(areApplyList, new Date());
            List<Long> existAreaList = waitPassDetail.stream().map(AreaApplyDetail::getArea).collect(Collectors.toList());
            List<Long> failAreaList = new ArrayList<>();
            existAreaList.addAll(existUserAgent.stream().map(UserAgentLevel::getLocationId).collect(Collectors.toList()));
            areaList.stream().forEach(item -> {
                if (existAreaList.contains(item.getArea())) {
                    failAreaList.add(item.getArea());
                }
            });

            if (!CollectionUtils.isEmpty(failAreaList)) {
                return new BaseResp(ResultCode.AREA_APPLY_FAIL);
            }

            String areaPrice = hipoConfigMapper.findValueByName(HipoConfigEnum.AREA_PRICE.getConfig());

            req.setUserId(user.getId());
            req.setAreaCount(areaList.size());
            req.setStatus(AreaApplyStatusEnum.WAIT_AUDIT.getStatus());
            req.setAmount(new BigDecimal(areaPrice).multiply(new BigDecimal(areaList.size())).setScale(2, BigDecimal.ROUND_HALF_DOWN));
            req.setCreatedAt(new Date());
            req.setUpdatedAt(new Date());
            areaApplyMapper.insert(req);

            List<AreaApplyDetail> areaApplyDetailList = new ArrayList<>();
            areaList.stream().forEach(item -> {
                areaApplyDetailList.add(AreaApplyDetail.builder().userId(user.getId()).areaApplyId(req.getId()).area(item.getArea()).status(AreaApplyStatusEnum.WAIT_AUDIT.getStatus()).province(item.getProvince()).city(item.getCity()).createdAt(new Date()).updatedAt(new Date()).build());
            });
            areaApplyDetailMapper.batchInsert(areaApplyDetailList);
        }
        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<AreaApplyVO>> getAreaApplyPage(AreaApplyPageReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        req.setUserId(user.getId());
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<AreaApplyVO> list = areaApplyMapper.findAllPage(req);
        if (!CollectionUtils.isEmpty(list)) {
            List<AreaApplyDetail> areaApplyDetailList = areaApplyDetailMapper.findAllByAreaApplyIds(list.stream().map(AreaApplyVO::getId).collect(Collectors.toList()));
            List<Area> areaList = areaMapper.findAllbyIds(areaApplyDetailList.stream().map(AreaApplyDetail::getArea).collect(Collectors.toList()));
            Map<Long, Area> areaMap = new HashMap<>();
            areaList.stream().forEach(item -> {
                areaMap.put(item.getId(), item);
            });
            Map<Long, List<AreaApplyDetailVO>> areaApplyMap = new HashMap<>();
            areaApplyDetailList.stream().forEach(item -> {
                List<AreaApplyDetailVO> newAreaApplyDetails = areaApplyMap.get(item.getAreaApplyId());
                if (newAreaApplyDetails == null) {
                    newAreaApplyDetails = new ArrayList<>();
                    AreaApplyDetailVO vo = new AreaApplyDetailVO();
                    BeanUtils.copyProperties(item, vo);
                    vo.setAreaName(areaMap.get(vo.getArea()).getName());
                    newAreaApplyDetails.add(vo);
                } else {
                    AreaApplyDetailVO vo = new AreaApplyDetailVO();
                    BeanUtils.copyProperties(item, vo);
                    vo.setAreaName(areaMap.get(vo.getArea()).getName());
                    newAreaApplyDetails.add(vo);
                }
                areaApplyMap.put(item.getAreaApplyId(), newAreaApplyDetails);
            });
            list.stream().forEach(item -> {
                item.setAreaApplyDetails(areaApplyMap.get(item.getId()));
            });
        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public BaseResp cancelAreaApply(Long id) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        AreaApply areaApply = areaApplyMapper.selectByPrimaryKey(id);
        if (areaApply.getUserId().equals(user.getId()) && AreaApplyStatusEnum.WAIT_AUDIT.getStatus().equals(areaApply.getStatus())) {
            areaApplyMapper.cancelAreaApply(AreaApplyStatusEnum.CANCEL.getStatus(), id);
            areaApplyDetailMapper.cancelAreaApply(AreaApplyStatusEnum.CANCEL.getStatus(), id);
        }
        return new BaseResp();
    }

    @Override
    public ResultData<AreaApplyVO> getAreaApplyDetail(Long id) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        AreaApplyVO vo = new AreaApplyVO();
        AreaApply areaApply = areaApplyMapper.selectByPrimaryKey(id);
        if (areaApply.getUserId().equals(user.getId())) {
            BeanUtils.copyProperties(areaApply, vo);
            List<AreaApplyDetail> areaApplyDetails = areaApplyDetailMapper.findAllByAreaApplyId(id);
            List<AreaApplyDetailVO> voList = new ArrayList<>();
            List<Area> areaList = areaMapper.findAllbyIds(areaApplyDetails.stream().map(AreaApplyDetail::getArea).collect(Collectors.toList()));
            Map<Long, Area> areaMap = new HashMap<>();
            areaList.stream().forEach(item -> {
                areaMap.put(item.getId(), item);
            });
            areaApplyDetails.stream().forEach(item -> {
                AreaApplyDetailVO detailVO = new AreaApplyDetailVO();
                BeanUtils.copyProperties(item, detailVO);
                detailVO.setAreaName(areaMap.get(detailVO.getArea()).getName());
                voList.add(detailVO);
            });
            vo.setAreaApplyDetails(voList);
        }
        return new ResultData<>(vo);
    }

    @Override
    public BaseResp deleteAreaApply(Long id) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        AreaApply areaApply = areaApplyMapper.selectByPrimaryKey(id);
        if (areaApply.getUserId().equals(user.getId()) && (!AreaApplyStatusEnum.PASS.getStatus().equals(areaApply.getStatus()))) {
            areaApplyMapper.deleteByPrimaryKey(id);
            areaApplyDetailMapper.deleteByAreaApplyId(id);
        }
        return new BaseResp();
    }

    @Override
    public BaseResp editSuggestion(Suggestion req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        req.setUserId(user.getId());
        if (req.getId() == null) {
            Suggestion suggestion = Suggestion.builder().userId(user.getId()).content(req.getContent()).createdAt(new Date()).build();
            suggestionMapper.insert(suggestion);
        } else {
            suggestionMapper.updateByPrimaryKeySelective(req);
        }
        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<DayCommissionVO>> getDayCommissionPage(PageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<DayCommissionVO> list = userCommissionMapper.getDayCommission(req);
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<AreaHomeStatisticsVO> getAreaHomeStatistics() {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        AreaHomeStatisticsVO vo = new AreaHomeStatisticsVO();
        List<UserAgentLevel> userAgentLevelList = userAgentLevelMapper.findAllByUserIdAndExpireTime(user.getId(), new Date());
        vo.setPoint(user.getPoint());
        if (!CollectionUtils.isEmpty(userAgentLevelList)) {
            vo.setAreaCount(Long.valueOf(userAgentLevelList.size()));
            vo.setPartnerCount(areaPartnerMapper.countByUserId(user.getId()));
            vo.setExpireTime(userAgentLevelList.get(0).getExpireTime());
            List<UserAgentVO> userAgentVOS = new ArrayList<>();
            userAgentLevelList.stream().forEach(item -> {
                UserAgentVO userAgentVO = new UserAgentVO();
                BeanUtils.copyProperties(item, userAgentVO);
                String mergerName = item.getMergerName();
                String[] split = mergerName.split(",");
                if (split.length >= 2) {
                    userAgentVO.setCityAndAreaName(split[split.length - 2] + "-" + split[split.length - 1]);
                } else {
                    userAgentVO.setCityAndAreaName(split[split.length - 1]);
                }
                userAgentVOS.add(userAgentVO);
            });
            vo.setUserAgentLevelList(userAgentVOS);
        }
        List<Byte> types = new ArrayList<>();
        types.add(UserCommissionTypeEnum.AREA_PARTNER_COMMISSION.getType());
        vo.setIncomeTimeVO(userCommissionMapper.getIncomeTime(user.getId(), types));
        return new ResultData<>(vo);
    }

    @Override
    public ResultData<BasePageResp<AreaPartnerVO>> getAreaPartnerPage(AreaPartnerPageReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        req.setUserId(user.getId());
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<AreaPartnerVO> list = areaPartnerMapper.findAllPage(req);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, User> userMap = daoService.getUserMap(list.stream().map(AreaPartner::getUserId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setLevel(userMap.get(item.getUserId()).getLevel());
            });
        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<MyGroupVO> getMyGroupStatistics(User user) {
        MyGroupVO vo = new MyGroupVO();
        vo.setInviteAttention(userGroupMapper.countByCaptainId(user.getId()));
        vo.setMember(userRelationshipMapper.countBySuperiorIdAndStatus(user.getId(), RelationshipStatusEnum.BIND.getStatus()));
        vo.setConsume(ordersMapper.sumConsume(user.getId()));
        //显示改为余额
//        StatisticsVO statisticsVO = userCommissionMapper.sumPerformanceCommissionByType(user.getId(), UserCommissionTypeEnum.MEMBER_SHARE_COMMISSION.getType());
        StatisticsVO statisticsVO = userCommissionMapper.sumPerformanceCommissionByType(user.getId(), UserCommissionTypeEnum.CO_FOUNDER_DIRECT_PUSH_REBATE.getType());
        vo.setPerformance(statisticsVO == null || statisticsVO.getStatisticsAmount() == null ? BigDecimal.ZERO : statisticsVO.getStatisticsAmount());
        vo.setCommission(statisticsVO == null || statisticsVO.getStatisticsMoney() == null ? BigDecimal.ZERO : statisticsVO.getStatisticsMoney());
        vo.setConfig(hipoConfigMapper.findValueByName(HipoConfigEnum.EXCHANGE_RATE.getConfig()));
        return new ResultData<>(vo);
    }

    @Override
    public BaseResp switchIdentity(User user, Byte type) {
        Identity identity = identityMapper.findOneByUserId(user.getId());
        if (PARTNER.getType().equals(type) || SHAREHOLDER.getType().equals(type)) {
            if (identity.getType() < type) {
                return new BaseResp(ResultCode.SWITCH_IDENTITY_FAIL);
            }
        } else if (MEMBER.getType().equals(type)) {
            if (identity.getMemberState() < 1) {
                return new BaseResp(ResultCode.NOT_AGENT_MEMBER);
            }
        } else if (ANCHOR.getType().equals(type)) {
            if (identity.getAnchorLevel() == 0) {
                return new BaseResp(ResultCode.NOT_ANCHOR);
            }
        } else if (AGENT.getType().equals(type)) {
            UserAgentLevel userAgent = userAgentLevelMapper.findOneByUserId(user.getId());
            if (userAgent == null) {
                return new BaseResp(ResultCode.DO_NOT_HAVE_AREA);
            }
        } else if (TEACHER.getType().equals(type)) {
            if (identity.getTeacherLevel() == 0) {
                return new BaseResp(ResultCode.NOT_TEACHER);
            }
        } else if (RECOMMEND.getType().equals(type)) {
            if (identity.getRecommendLevel() <= 0) {
                return new BaseResp(ResultCode.NOT_RECOMMEND);
            }
        } else if (BOSS.getType().equals(type)) {
            BossIdentity bossIdentity = bossIdentityMapper.findOneByUserId(user.getId());
            if (bossIdentity == null || bossIdentity.getBossLevel() <= 0) {
                return new BaseResp(ResultCode.NOT_BOSS);
            }
        } else if (AGENT_MEMBER.getType().equals(type)) {
            if (identity.getMemberState() < 2) {
                return new BaseResp(ResultCode.NOT_AGENT_MEMBER);
            }
        } else if (UNION_FOUNDER.getType().equals(type)) {
            if (ToggleEnum.OFF.getStatus().equals(identity.getDirector())) {
                return new BaseResp(ResultCode.NOT_UNION_FOUNDER);
            }
        } else if (COMPANY.getType().equals(type)) {
            if (ShareholderStateEnum.DEFAULT.getType().equals(identity.getShareholderState())) {
                return new BaseResp(ResultCode.NOT_COMPANY);
            }
        }
        CurrentIdentity selectIdentity = currentIdentityMapper.findOneByUserId(user.getId());
        if (selectIdentity == null) {
            currentIdentityMapper.insert(CurrentIdentity.builder().userId(user.getId()).allIdentityType(type).updatedAt(new Date()).build());
        } else {
            selectIdentity.setAllIdentityType(type);
            selectIdentity.setUpdatedAt(new Date());
            currentIdentityMapper.updateByPrimaryKey(selectIdentity);
        }

        return new BaseResp();
    }

    @Override
    public BaseResp changeBossRelationship(User user, String inviteCode) {
        BossRelationship bossRelationship = bossRelationshipMapper.findOneBySubordinateId(user.getId());
        Long superiorId = inviteCodeService.decodeInviteCode(inviteCode);

        if (superiorId == null) {
            return new BaseResp();
        }

        if (user.getId().equals(superiorId)) {
            return new BaseResp();
        }

        BossIdentity bossIdentity = bossIdentityMapper.findOneByUserId(superiorId);
        if (bossIdentity == null || bossIdentity.getBossLevel() <= 0) {
            return new BaseResp(ResultCode.INVITE_NOT_BOSS);
        }

        if (bossRelationship == null) {
            bossRelationshipMapper.insert(BossRelationship.builder().superiorId(superiorId).subordinateId(user.getId()).createdAt(new Date()).updatedAt(new Date()).status(RelationshipStatusEnum.NOT_BIND.getStatus()).build());
        } else {
            if (RelationshipStatusEnum.NOT_BIND.getStatus().equals(bossRelationship.getStatus()) && !bossRelationship.getSuperiorId().equals(superiorId)) {
                bossRelationship.setSuperiorId(superiorId);
                bossRelationship.setUpdatedAt(new Date());
                bossRelationshipMapper.updateByPrimaryKeySelective(bossRelationship);
            }
        }
        return new BaseResp();
    }

    @Override
    public String testAudioUrl() {
        try {
            return baiduService.createAudio("123");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public BaseResp changePointToCardPoint(BigDecimal amount) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (user.getPoint().compareTo(amount) < 0 && amount.compareTo(BigDecimal.ZERO) > 0) {
            return new BaseResp(ResultCode.INSUFFICIENT_BALANCE);
        }
        userMapper.changePointAndCardPoint(amount, user.getId());
        cardFlowMapper.insert(CardFlow.builder().userId(user.getId()).amount(amount).tradeType(CardTradeTypeEnum.POINT_TO_CARD_POINT.getTradeType()).type(CardTradeTypeEnum.POINT_TO_CARD_POINT.getType()).cardPoint(user.getCardPoint().add(amount)).remark("佣金转换成嗨币").createdAt(new Date()).build());
        balanceFlowMapper.insert(BalanceFlow.builder().userId(user.getId()).amount(amount).tradeType(TradeTypeEnum.POINT_TO_CARD_POINT.getTradeType()).type(TradeTypeEnum.POINT_TO_CARD_POINT.getType()).point(user.getPoint().subtract(amount)).remark("转换成嗨币").createdAt(new Date()).build());
        return new BaseResp();
    }

    @Override
    public ResultData<InviteBuyStatisticsVO> getMyInviteFirstBuyStatistics() {
        InviteBuyStatisticsVO vo = new InviteBuyStatisticsVO();
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        vo.setRewardCount(inviteFirstBuyMapper.countBySuperiorIdAndStatus(user.getId(), InviteFirstBuyStatusEnum.REWARD.getStatus()));
        vo.setNoRewardCount(inviteFirstBuyMapper.countBySuperiorIdAndStatus(user.getId(), InviteFirstBuyStatusEnum.NOT_REWARD.getStatus()));
        vo.setCancelRewardCount(inviteFirstBuyMapper.countBySuperiorIdAndStatus(user.getId(), InviteFirstBuyStatusEnum.CANCEL.getStatus()));
        PerformanceAmount performanceAmount = performanceAmountMapper.selectByPrimaryKey(PerformanceIdEnum.MEMBER_INVITE.getId());
        vo.setPerformanceAmount(performanceAmount.getPerformance());
        vo.setCountRound(performanceAmount.getCountRound());
        return new ResultData<>(vo);
    }

    @Override
    public BaseResp transferCardPoint(TransferCardPointReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        //校验安全密码
        BaseResp baseResp = checkSecurityPassword(req.getPayPassword(), user);
        if (baseResp != null) {
            return baseResp;
        }

        //转账用户是否存在
        User transferUser = userMapper.findOneByUsername(req.getPhone());
        if (transferUser == null) {
            return new BaseResp(ResultCode.USER_NOT_EXISTS);
        }

        if (transferUser.getId().equals(user.getId())) {
            return new BaseResp(ResultCode.IS_CURRENT_USER);
        }

        if (user.getCardPoint().compareTo(req.getAmount()) < 0) {
            return new BaseResp(ResultCode.CARD_POINT_NOT_ENOUGH);
        }

        //创建嗨币流水
        List<CardFlow> cardFlowList = new ArrayList<>();
        BigDecimal subtract = user.getCardPoint().subtract(req.getAmount());
        BigDecimal add = transferUser.getCardPoint().add(req.getAmount());
        cardFlowList.add(CardFlow.builder().userId(user.getId()).amount(req.getAmount()).tradeType(CardTradeTypeEnum.TRANSFER_ACCOUNTS_REFUND.getTradeType()).type(CardTradeTypeEnum.TRANSFER_ACCOUNTS_REFUND.getType()).cardPoint(subtract).remark("嗨币转账支出").createdAt(new Date()).relateId(transferUser.getId()).build());
        cardFlowList.add(CardFlow.builder().userId(transferUser.getId()).amount(req.getAmount()).tradeType(CardTradeTypeEnum.TRANSFER_ACCOUNTS_REWARD.getTradeType()).type(CardTradeTypeEnum.TRANSFER_ACCOUNTS_REWARD.getType()).cardPoint(add).remark("嗨币转账收入").createdAt(new Date()).relateId(user.getId()).build());
        cardFlowMapper.batchInsert(cardFlowList);

        //更新用户嗨币
        userMapper.updateCardPointById(subtract, user.getId());
        userMapper.updateCardPointById(add, transferUser.getId());

        return new BaseResp();
    }

    /**
     * 校验安全密码
     *
     * @param securityPassword
     * @param user
     * @throws ResultCodeException
     */
    private BaseResp checkSecurityPassword(String securityPassword, User user) {
        if (user.getPayPassword() == null) {
            return new BaseResp(ResultCode.NOT_HAS_PAY_PASSWORD);
        }
        if (!StringUtils.isEmpty(securityPassword)) {
            ValueOperations<String, Integer> operations = redisTemplate.opsForValue();
            Integer count = operations.get("PayPasswordError:" + user.getId().toString());
            if (count != null && count >= 5) {
                return new BaseResp(ResultCode.AFTER_ONE_MINUTE);
            }
            if (!new BCryptPasswordEncoder().matches(securityPassword, user.getPayPassword())) {
                operations.set("PayPasswordError:" + user.getId(), count == null ? 1 : count + 1, 1, TimeUnit.MINUTES);
                return new BaseResp(ResultCode.PAY_PASSWORD_ERROR);
            }
        } else {
            return new BaseResp(ResultCode.NEED_SECURITY_PASSWORD);
        }
        return null;
    }

    @Override
    public ResultData<BasePageResp<GiveIdentityRecordVO>> getMyGiveIdentityRecordPage(GiveIdentityRecordPageReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        req.setFromUserId(user.getId());
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<GiveIdentityRecordVO> list = giveIdentityRecordMapper.findAllPage(req);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, User> userMap = daoService.getUserMap(list.stream().map(GiveIdentityRecordVO::getToUserId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setToNickname(userMap.get(item.getToUserId()).getNickname());
                item.setToAvatar(userMap.get(item.getToUserId()).getAvatar());
                item.setToUserPhone(userMap.get(item.getToUserId()).getUsername());
            });
        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public BaseResp subscribeFlashSaleSpu(SubscribeRecord req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        FlashSaleSpu flashSaleSpu = flashSaleSpuMapper.selectByPrimaryKey(req.getRelateId());
        if (flashSaleSpu != null && ToggleEnum.ON.getStatus().equals(flashSaleSpu.getStatus())) {
            FlashSaleActivity flashSaleActivity = flashSaleActivityMapper.selectByPrimaryKey(flashSaleSpu.getActivityId());
            if (flashSaleActivity != null && ToggleEnum.ON.getStatus().equals(flashSaleActivity.getStatus())) {

                Calendar calendar = Calendar.getInstance();
                calendar.setTime(flashSaleActivity.getStartTime());
                calendar.add(Calendar.MINUTE, -10);
                if (System.currentTimeMillis() > calendar.getTimeInMillis()) {
                    return new BaseResp(ResultCode.SUBSCRIBE_FAIL);
                }

                SubscribeRecord subscribeRecord = subscribeRecordMapper.findOneByUserIdAndRelateId(user.getId(), req.getRelateId());
                if (subscribeRecord == null) {
                    subscribeRecordMapper.insert(SubscribeRecord.builder().userId(user.getId()).relateId(req.getRelateId()).type(SubscribeRecordTypeEnum.FLASH_SALE.getType()).createdAt(new Date()).subscribeClient(req.getSubscribeClient()).activityId(flashSaleActivity.getId()).build());
                }

                TriggerKey triggerKey = TriggerKey.triggerKey("FLASH_TRIGGER" + flashSaleSpu.getActivityId().toString(), "FLASH_SALE_NOTIFY");
                try {
                    //是否存在当前活动的定时任务
                    Trigger trigger = scheduler.getTrigger(triggerKey);
                    if (trigger == null) {
                        //设置订阅提示定时任务
                        quartzService.createFlashSaleJob(flashSaleActivity);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    log.info(e.getMessage());
                }
            } else {
                return new BaseResp(ResultCode.ACTIVITY_HAS_END);
            }
        } else {
            return new BaseResp(ResultCode.SUBSCRIBE_SPU_FAIL);
        }
        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<SubscribeRecordVO>> getMySubscribeRecordPage(SubscribeRecordPageReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        req.setUserId(user.getId());
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<SubscribeRecordVO> list = subscribeRecordMapper.findAllPage(req);
        if (!CollectionUtils.isEmpty(list)) {
            List<FlashSaleSpu> flashSaleSpus = flashSaleSpuMapper.findAllByIdIn(list.stream().map(SubscribeRecordVO::getRelateId).collect(Collectors.toList()));
            Map<Long, FlashSaleSpu> flashSaleSpuMap = new HashMap<>();
            flashSaleSpus.stream().forEach(item -> {
                flashSaleSpuMap.put(item.getId(), item);
            });
            List<FlashSaleActivity> flashSaleActivities = flashSaleActivityMapper.findAllByIdIn(list.stream().map(SubscribeRecordVO::getActivityId).collect(Collectors.toList()));
            Map<Long, FlashSaleActivity> flashSaleActivityMap = new HashMap<>();
            flashSaleActivities.stream().forEach(item -> {
                flashSaleActivityMap.put(item.getId(), item);
            });

            list.stream().forEach(item -> {
                item.setFlashSaleSpu(flashSaleSpuMap.get(item.getRelateId()));
                item.setFlashSaleActivity(flashSaleActivityMap.get(flashSaleSpuMap.get(item.getRelateId()).getActivityId()));
            });
        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public BaseResp cancelSubscribeFlashSaleSpu(Long relateId) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        SubscribeRecord subscribeRecord = subscribeRecordMapper.findOneByUserIdAndRelateIdAndType(user.getId(), relateId, SubscribeRecordTypeEnum.FLASH_SALE.getType());
        if (subscribeRecord != null && subscribeRecord.getUserId().equals(user.getId())) {
            subscribeRecordMapper.deleteByPrimaryKey(subscribeRecord.getId());

            //没人订阅关闭定时任务
            Long subscribeCount = subscribeRecordMapper.countByActivityId(subscribeRecord.getActivityId());
            if (subscribeCount == 0) {
                TriggerKey triggerKey = TriggerKey.triggerKey("FLASH_TRIGGER" + subscribeRecord.getActivityId().toString(), "FLASH_SALE_NOTIFY");
                JobKey jobKey = JobKey.jobKey("FLASH_JOB" + subscribeRecord.getActivityId().toString(), "FLASH_SALE_NOTIFY");
                try {
                    //关闭定时任务
                    scheduler.pauseTrigger(triggerKey);
                    // 移除触发器中的任务
                    scheduler.unscheduleJob(triggerKey);
                    // 删除任务
                    scheduler.deleteJob(jobKey);
                } catch (SchedulerException e) {
                    e.printStackTrace();
                }
            }
        }
        return new BaseResp();
    }

    @Override
    public ResultData<IncomeTimeVO> getMyIncomeChange(User user) {
        return new ResultData<>(userCommissionMapper.getIncomeChange(user.getId()));
    }

    @Override
    public ResultData<BasePageResp<StatisticsVO>> getOrderSkuByTimeTypePage(TimeTypeReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (req.getTimeType() != null) {
            Calendar startCalendar = Calendar.getInstance();
            startCalendar.setTime(req.getDate());
            Calendar endCalendar = Calendar.getInstance();
            endCalendar.setTime(req.getDate());
            req.setStartTime(getFirstTimeByTimeType(startCalendar, req.getTimeType()));
            req.setEndTime(getEndTimeByTimeType(endCalendar, req.getTimeType()));
        }
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<StatisticsVO> list = orderSkuMapper.getOrderSkuByTimeType(req);
        if (!CollectionUtils.isEmpty(list)) {
            list.stream().forEach(item -> {
                item.setStatisticsAmount(item.getStatisticsMoney().multiply(new BigDecimal(hipoConfigMapper.findValueByName(HipoConfigEnum.DIRECTOR_COMMISSION_RATE.getConfig()))).setScale(2, BigDecimal.ROUND_UP));
                item.setAvgMoney(item.getStatisticsAmount().divide(new BigDecimal("200"), 2, BigDecimal.ROUND_DOWN));
            });
        }
        ResultData<BasePageResp<StatisticsVO>> basePageRespResultData = PageHelpUtil.buildPage(list, page);
        basePageRespResultData.getValue().setExtra(userCommissionMapper.sumBySuperiorIdAndType(user.getId(), UserCommissionTypeEnum.DIRECTOR_COMMISSION.getType()));
        return basePageRespResultData;
    }

    @Override
    public BaseResp editReport(Report report) {
        if (report.getId() == null) {
            report.setStatus(ReportStatusEnum.WAIT_HANDLE.getStatus());
            report.setCreatedAt(new Date());
            reportMapper.insert(report);
        }
        return new BaseResp();
    }

    @Override
    public ResultData<StaticDividendDetailVO> getStaticDividendDetail(TimeRangeReq req) {
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(req.getDate());
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(req.getDate());
        req.setStartTime(getFirstTimeByTimeType(startCalendar, req.getTimeType()));
        req.setEndTime(getEndTimeByTimeType(endCalendar, req.getTimeType()));
        List<DividendPrecipitationVO> monthDividend = dividendPrecipitationMapper.findAllByTypeAndWeekTimeRange(DividendPrecipitationTypeEnum.MARKET_SUBSIDY.getType(), req.getStartTime(), req.getEndTime());
        if (monthDividend == null || monthDividend.size() == 0) {
            monthDividend = new ArrayList<>();
            DividendPrecipitation lastOne = dividendPrecipitationMapper.findLastOne(DividendPrecipitationTypeEnum.MARKET_SUBSIDY.getType());
            DividendPrecipitationVO vo = new DividendPrecipitationVO();
            BeanUtils.copyProperties(lastOne, vo);
            monthDividend.add(vo);
        }

        Map<String, String> config = daoService.getHipoConfigMap();
        BigDecimal memberLimit = new BigDecimal(config.get(HipoConfigEnum.MEMBER_STATIC_DIVIDEND_LIMIT.getConfig()));
        BigDecimal partnerLimit = new BigDecimal(config.get(HipoConfigEnum.PARTNER_STATIC_DIVIDEND_LIMIT.getConfig()));
        BigDecimal shareholderLimit = new BigDecimal(config.get(HipoConfigEnum.SHAREHOLDER_STATIC_DIVIDEND_LIMIT.getConfig()));
        Long memberCount = identityMapper.sumStaticDividendMember(IdentityTypeEnum.MEMBER.getType(), MemberStateEnum.SUPER.getType(), memberLimit, new Date());
        Long partnerCount = identityMapper.sumStaticDividendPartner(IdentityTypeEnum.PARTNER.getType(), partnerLimit, new Date());
        Long shareholderCount = identityMapper.sumStaticDividendShareholder(IdentityTypeEnum.SHAREHOLDER.getType(), shareholderLimit, new Date());

        StaticDividendDetailVO vo = new StaticDividendDetailVO();
        vo.setList(monthDividend);
        vo.setSumCount(memberCount + partnerCount + shareholderCount);

        return new ResultData<>(vo);
    }

    @Override
    public ResultData<StaticDividendDetailVO> getMemberDividendDetail(TimeRangeReq req) {
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(req.getDate());
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(req.getDate());
        req.setStartTime(getFirstTimeByTimeType(startCalendar, req.getTimeType()));
        req.setEndTime(getEndTimeByTimeType(endCalendar, req.getTimeType()));
        List<DividendPrecipitationVO> monthDividend = dividendPrecipitationMapper.findAllByTypeAndWeekTimeRange(DividendPrecipitationTypeEnum.MEMBER.getType(), req.getStartTime(), req.getEndTime());
        if (monthDividend == null || monthDividend.size() == 0) {
            monthDividend = new ArrayList<>();
            DividendPrecipitation lastOne = dividendPrecipitationMapper.findLastOne(DividendPrecipitationTypeEnum.MEMBER.getType());
            DividendPrecipitationVO vo = new DividendPrecipitationVO();
            BeanUtils.copyProperties(lastOne, vo);
            monthDividend.add(vo);
        }

        Long memberLevel2Count = identityMapper.countByMemberLevel(UserLevelEnum.MEMBER_L2.getLevel(), new Date());
        Long memberLevel3Count = identityMapper.countByMemberLevel(UserLevelEnum.MEMBER_L3.getLevel(), new Date());
        Long memberLevel4Count = identityMapper.countByMemberLevel(UserLevelEnum.MEMBER_L4.getLevel(), new Date());

        if (memberLevel2Count == null) memberLevel2Count = 0L;
        if (memberLevel3Count == null) memberLevel3Count = 0L;
        if (memberLevel4Count == null) memberLevel4Count = 0L;

        StaticDividendDetailVO vo = new StaticDividendDetailVO();
        vo.setList(monthDividend);
        vo.setSumCount(memberLevel2Count + memberLevel3Count + memberLevel4Count);

        return new ResultData<>(vo);
    }

    @Override
    public ResultData<SumStaticDividendVO> getTotalStaticDividend() {
        DividendPrecipitation result = dividendPrecipitationMapper.sumAllByType(DividendPrecipitationTypeEnum.MARKET_SUBSIDY.getType());

        Map<String, String> config = daoService.getHipoConfigMap();
        BigDecimal memberLimit = new BigDecimal(config.get(HipoConfigEnum.MEMBER_STATIC_DIVIDEND_LIMIT.getConfig()));
        BigDecimal partnerLimit = new BigDecimal(config.get(HipoConfigEnum.PARTNER_STATIC_DIVIDEND_LIMIT.getConfig()));
        BigDecimal shareholderLimit = new BigDecimal(config.get(HipoConfigEnum.SHAREHOLDER_STATIC_DIVIDEND_LIMIT.getConfig()));
        Long memberCount = identityMapper.sumStaticDividendMember(IdentityTypeEnum.MEMBER.getType(), MemberStateEnum.SUPER.getType(), memberLimit, new Date());
        Long partnerCount = identityMapper.sumStaticDividendPartner(IdentityTypeEnum.PARTNER.getType(), partnerLimit, new Date());
        Long shareholderCount = identityMapper.sumStaticDividendShareholder(IdentityTypeEnum.SHAREHOLDER.getType(), shareholderLimit, new Date());

        SumStaticDividendVO vo = new SumStaticDividendVO();
        vo.setDividendPrecipitation(result);
        vo.setSumCount(memberCount + partnerCount + shareholderCount);

        vo.setArticleList(articleMapper.findAllByCatalogOrderByTopDesc(ArticleCatalogEnum.NOTICE.getCatalog()));
        return new ResultData<>(vo);
    }

    @Override
    public ResultData<BasePageResp<DividendOrderVO>> getStaticDividendOrderPage(TimeRangeReq req) {
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(req.getDate());
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(req.getDate());
        req.setStartTime(getFirstTimeByTimeType(startCalendar, req.getTimeType()));
        req.setEndTime(getEndTimeByTimeType(endCalendar, req.getTimeType()));
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<DividendOrderVO> list = ordersMapper.findStaticDividendOrderPage(req);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, User> userMap = daoService.getUserMap(list.stream().map(DividendOrderVO::getUserId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setIdentity(userMap.get(item.getUserId()).getLevel());
                item.setNickname(userMap.get(item.getUserId()).getNickname());
            });
        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<BasePageResp<WithdrawRespVO>> getWithdrawPage(PageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<WithdrawRespVO> list = withdrawMapper.findAllRespPage(req);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, User> userMap = daoService.getUserMap(list.stream().map(WithdrawRespVO::getUserId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setUserNickname(userMap.get(item.getUserId()).getNickname());
                item.setUserAvatar(userMap.get(item.getUserId()).getAvatar());
            });
        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<MemberPrecipitationVO> getMemberDividendPrecipitationDetail() {
        MemberPrecipitationVO vo = new MemberPrecipitationVO();
        vo.setDividendPrecipitation(dividendPrecipitationMapper.sumAllByType(DividendPrecipitationTypeEnum.MEMBER.getType()));
        vo.setMemberLevel2Count(identityMapper.countByMemberLevel(UserLevelEnum.MEMBER_L2.getLevel(), new Date()));
        vo.setMemberLevel3Count(identityMapper.countByMemberLevel(UserLevelEnum.MEMBER_L3.getLevel(), new Date()));
        vo.setMemberLevel4Count(identityMapper.countByMemberLevel(UserLevelEnum.MEMBER_L4.getLevel(), new Date()));
        return new ResultData<>(vo);
    }

    @Override
    public ResultData<StaticDividendDetailVO> getDirectorCommissionDetail(TimeRangeReq req) {
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(req.getDate());
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(req.getDate());
        req.setStartTime(getFirstTimeByTimeType(startCalendar, req.getTimeType()));
        req.setEndTime(getEndTimeByTimeType(endCalendar, req.getTimeType()));
        List<DividendPrecipitationVO> monthDividend = dividendPrecipitationMapper.findAllByTypeAndWeekTimeRange(DividendPrecipitationTypeEnum.DIRECTOR.getType(), req.getStartTime(), req.getEndTime());
        if (monthDividend == null || monthDividend.size() == 0) {
            monthDividend = new ArrayList<>();
            DividendPrecipitation lastOne = dividendPrecipitationMapper.findLastOne(DividendPrecipitationTypeEnum.DIRECTOR.getType());
            DividendPrecipitationVO vo = new DividendPrecipitationVO();
            BeanUtils.copyProperties(lastOne, vo);
            monthDividend.add(vo);
        }

        StaticDividendDetailVO vo = new StaticDividendDetailVO();
        vo.setList(monthDividend);
        vo.setSumCount(Long.valueOf(DIRECTOR_COUNT));

        return new ResultData<>(vo);
    }

    @Override
    public ResultData<BasePageResp<UserCommissionResp>> getUserCommissionPage(UserCommissionReq req) {

        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(req.getDate());
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(req.getDate());

        req.setStartTime(getFirstTimeByTimeType(startCalendar, req.getTimeType()));
        req.setEndTime(getEndTimeByTimeType(endCalendar, req.getTimeType()));

        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<UserCommissionResp> list = userCommissionMapper.findAllPage(req);
        if (CollectionUtils.isEmpty(list)) {
            return PageHelpUtil.buildPage(list, page);
        }
        List<Long> userIds = new ArrayList<>();
        list.stream().forEach(item -> {
            if (!userIds.contains(item.getSuperiorId())) {
                userIds.add(item.getSuperiorId());
            }
            if (!userIds.contains(item.getSubordinateId())) {
                userIds.add(item.getSubordinateId());
            }
        });

        Map<Long, User> userMap = daoService.getUserMap(userIds);

        list.stream().forEach(item -> {
            item.setSuperiorNickname(userMap.get(item.getSuperiorId()).getNickname());
            item.setSuperiorAvatar(userMap.get(item.getSuperiorId()).getAvatar());
            item.setSuperiorLevel(userMap.get(item.getSuperiorId()).getLevel());

            item.setSubordinateNickname(userMap.get(item.getSubordinateId()).getNickname());
            item.setSubordinateAvatar(userMap.get(item.getSubordinateId()).getAvatar());
            item.setSubordinateLevel(userMap.get(item.getSubordinateId()).getLevel());
        });

        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<BasePageResp<DividendMemberVO>> getStaticDividendMemberPage(TimeRangeReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        req.setDate(new Date());
        List<DividendMemberVO> list = identityMapper.findAllDividendMember(req);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, User> userMap = daoService.getUserMap(list.stream().map(DividendMemberVO::getUserId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setNickname(userMap.get(item.getUserId()).getNickname());
                item.setAvatar(userMap.get(item.getUserId()).getAvatar());
            });
        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<BasePageResp<DividendItemVO>> getMemberDividendMemberPage(DividendPageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        req.setNow(new Date());
        List<DividendItemVO> list = identityMapper.findAllByDividendPage(req);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, User> userMap = daoService.getUserMap(list.stream().map(DividendItemVO::getUserId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setNickname(userMap.get(item.getUserId()).getNickname());
                item.setAvatar(userMap.get(item.getUserId()).getAvatar());
            });
        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<BasePageResp<WithdrawRespVO>> getWithdrawRankPage(PageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<WithdrawRespVO> list = withdrawMapper.findWithdrawRank(req);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, User> userMap = daoService.getUserMap(list.stream().map(WithdrawRespVO::getUserId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setUserNickname(userMap.get(item.getUserId()).getNickname());
                item.setUserAvatar(userMap.get(item.getUserId()).getAvatar());
            });
        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<BasePageResp<UserCommissionResp>> getAllCommissionPage(UserCommissionReq req) {
        if (req.getSuperiorPhone() != null) {
            User user = userMapper.findOneByUsername(req.getSuperiorPhone());
            req.setSuperiorId(user != null ? user.getId() : 0L);
        }
        if (req.getSuperiorNickname() != null) {
            List<Long> userIds = userMapper.findIdByNicknameLike(req.getSuperiorNickname());
            if (userIds.size() == 0) {
                userIds.add(0L);
            }
            req.setUserIds(userIds);
        }
        if (req.getTimeType() != null) {
            Calendar startCalendar = Calendar.getInstance();
            startCalendar.setTime(req.getDate());
            Calendar endCalendar = Calendar.getInstance();
            endCalendar.setTime(req.getDate());
            req.setStartTime(getFirstTimeByTimeType(startCalendar, req.getTimeType()));
            req.setEndTime(getEndTimeByTimeType(endCalendar, req.getTimeType()));
        }
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<UserCommissionResp> list = userCommissionMapper.findAllPage(req);

        if (CollectionUtils.isEmpty(list)) {
            return PageHelpUtil.buildPage(list, page);
        }

        List<Long> userIds = new ArrayList<>();
        list.stream().forEach(item -> {
            if (!userIds.contains(item.getSuperiorId())) {
                userIds.add(item.getSuperiorId());
            }
            if (!userIds.contains(item.getSubordinateId())) {
                userIds.add(item.getSubordinateId());
            }
        });

        Map<Long, User> userMap = daoService.getUserMap(userIds);

        Map<Long, OrderSku> orderSkuMap = daoService.getOrderSkuMap(list.stream().map(UserCommission::getOrderSkuId).collect(Collectors.toList()));

        list.stream().forEach(item -> {
            item.setSubordinateNickname(userMap.get(item.getSubordinateId()).getNickname());
            item.setSubordinateAvatar(userMap.get(item.getSubordinateId()).getAvatar());
            item.setSubordinateLevel(userMap.get(item.getSubordinateId()).getLevel());

            item.setSuperiorNickname(userMap.get(item.getSuperiorId()).getNickname());
            item.setSuperiorAvatar(userMap.get(item.getSuperiorId()).getAvatar());
            item.setSuperiorLevel(userMap.get(item.getSuperiorId()).getLevel());

            if (orderSkuMap.containsKey(item.getOrderSkuId())) {
                item.setOrderId(orderSkuMap.get(item.getOrderSkuId()).getOrderId());
                item.setProductName(orderSkuMap.get(item.getOrderSkuId()).getProductName());
            }
        });
        ResultData<BasePageResp<UserCommissionResp>> data = PageHelpUtil.buildPage(list, page);
        if (req.getNeedSum() != null && req.getNeedSum()) {
            StatisticsVO vo = userCommissionMapper.getCommissionPageStatistics(req);
            data.getValue().setExtra(vo);
        }
        return data;
    }

    @Override
    public ResultData<BasePageResp<UserDetailResp>> getAllUserPage(PageReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        List<UserDetailResp> list = new ArrayList<>();
        if (UserStaffTypeEnum.NOT_STAFF.getType().equals(user.getStaffType())) {
            return new ResultData<>();
        }
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<User> userList = userMapper.findAllPage(req);
        if (userList.size() > 0) {
            userList.stream().forEach(item -> {
                UserDetailResp resp = new UserDetailResp();
                BeanUtils.copyProperties(item, resp);
                list.add(resp);
            });
        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<BasePageResp<GroupsPerformanceVO>> getGroupsPerformancePage(GroupsPerformancePageReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        req.setUserId(user.getId());
        if (req.getDate() != null) {
            Calendar startCalendar = Calendar.getInstance();
            startCalendar.setTime(req.getDate());
            Calendar endCalendar = Calendar.getInstance();
            endCalendar.setTime(req.getDate());
            req.setStartTime(getFirstTimeByTimeType(startCalendar, req.getTimeType()));
            req.setEndTime(getEndTimeByTimeType(endCalendar, req.getTimeType()));
        }
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<GroupsPerformanceVO> list = groupsPerformanceMapper.findAllPage(req);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, OrderSku> orderSkuMap = daoService.getOrderSkuMap(list.stream().map(GroupsPerformanceVO::getOrderSkuId).collect(Collectors.toList()));
            List<Long> userIds = orderSkuMap.values().stream().map(OrderSku::getUserId).collect(Collectors.toList());
            userIds.addAll(list.stream().map(GroupsPerformanceVO::getUserId).collect(Collectors.toList()));
            Map<Long, User> userMap = daoService.getUserMap(userIds);
            list.stream().forEach(item -> {
                item.setToUserNickname(userMap.get(orderSkuMap.get(item.getOrderSkuId()).getUserId()).getNickname());
                item.setToUserAvatar(userMap.get(orderSkuMap.get(item.getOrderSkuId()).getUserId()).getAvatar());
                OrderSku orderSku = orderSkuMap.get(item.getOrderSkuId());
                if (orderSku != null) {
                    item.setProductName(orderSku.getProductName());
                }
            });
        }
        ResultData<BasePageResp<GroupsPerformanceVO>> basePageRespResultData = PageHelpUtil.buildPage(list, page);
        BigDecimal sum = groupsPerformanceMapper.sumGroupPerformance(req);
        basePageRespResultData.getValue().setExtra(sum == null ? BigDecimal.ZERO : sum);
        return basePageRespResultData;
    }

    @Override
    public ResultData<BasePageResp<ShareholderPerformanceVO>> getShareholderPerformancePage(ShareholderPerformancePageReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        req.setUserId(user.getId());
        if (req.getDate() != null) {
            Calendar startCalendar = Calendar.getInstance();
            startCalendar.setTime(req.getDate());
            Calendar endCalendar = Calendar.getInstance();
            endCalendar.setTime(req.getDate());
            req.setStartTime(getFirstTimeByTimeType(startCalendar, req.getTimeType()));
            req.setEndTime(getEndTimeByTimeType(endCalendar, req.getTimeType()));
        }
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<ShareholderPerformanceVO> list = shareholderPerformanceMapper.findAllPage(req);
        if (list.size() > 0) {
            Map<Long, OrderSku> orderSkuMap = daoService.getOrderSkuMap(list.stream().map(ShareholderPerformanceVO::getOrderSkuId).collect(Collectors.toList()));
            Map<Long, User> userMap = daoService.getUserMap(orderSkuMap.values().stream().map(OrderSku::getUserId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setProductName((orderSkuMap.get(item.getOrderSkuId())).getProductName());
                item.setBuyUserAvatar(userMap.get(orderSkuMap.get(item.getOrderSkuId()).getUserId()).getAvatar());
                item.setBuyUserNickname(userMap.get(orderSkuMap.get(item.getOrderSkuId()).getUserId()).getNickname());
            });
        }
        ResultData<BasePageResp<ShareholderPerformanceVO>> basePageRespResultData = PageHelpUtil.buildPage(list, page);
        PerformanceStatisticsVO vo = shareholderPerformanceMapper.sumShareholderPerformance(req);
        basePageRespResultData.getValue().setExtra(vo);
        return basePageRespResultData;
    }

    @Override
    public ResultData<BasePageResp<WelfareFlowVO>> getWelfareFlowPage(WelfareFlowPageReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        req.setUserId(user.getId());
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<WelfareFlowVO> list = welfareFlowMapper.findAllPage(req);
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public void testInviteReward(Long superiorId, Long userId) {
        User superiorUser = userMapper.selectByPrimaryKey(superiorId);
        User user = userMapper.selectByPrimaryKey(userId);
        checkAndUpdateInvoiceCount(user.getUsername(), user.getId(), superiorUser);
    }

    @Override
    public ResultData<BasePageResp<TicketVO>> getTicketPage(TicketPageReq req) {
        User currentUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (!"13157141999".equals(currentUser.getUsername())) {
            return null;
        }
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        req.setAdminId(HIPO_ADMIN_ID);
        req.setType(TicketTypeEnum.USER_LEVEL.getType());//筛选赠送用户身份审批
        List<TicketVO> list = ticketMapper.findAllPage(req);
        if (!CollectionUtils.isEmpty(list)) {
            List<Long> adminIds = list.stream().map(TicketVO::getAdminId).collect(Collectors.toList());
            adminIds.addAll(list.stream().map(TicketVO::getFirstAdminId).collect(Collectors.toList()));
            adminIds.addAll(list.stream().map(TicketVO::getSecondAdminId).collect(Collectors.toList()));
            Map<Long, Admin> adminMap = daoService.getAdminMap(adminIds);
            Map<Long, User> userMap = daoService.getUserMap(list.stream().map(TicketVO::getRelateId).collect(Collectors.toList()));
            Map<Long, Shop> shopMap = daoService.getShopMap(list.stream().map(TicketVO::getRelateId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                Admin applyAdmin = adminMap.get(item.getAdminId());
                item.setNickname(applyAdmin.getNickname());
                item.setAvatar(applyAdmin.getAvatar());
                item.setRealName(applyAdmin.getRealName());
                item.setFirstAvatar(adminMap.get(item.getFirstAdminId()).getAvatar());
                item.setFirstNickname(adminMap.get(item.getFirstAdminId()).getNickname());
                if (TicketLevelEnum.SECOND_AUDIT.getLevel().equals(item.getLevel())) {
                    item.setSecondAvatar(adminMap.get(item.getSecondAdminId()).getAvatar());
                    item.setSecondNickname(adminMap.get(item.getSecondAdminId()).getNickname());
                }
                if (TicketTypeEnum.EXCHANGE_BALANCE.getType().equals(item.getType()) || TicketTypeEnum.COMMISSION.getType().equals(item.getType())) {
                    if (userMap.containsKey(item.getRelateId())) {
                        item.setUserAvatar(userMap.get(item.getRelateId()).getAvatar());
                        item.setUserNickname(userMap.get(item.getRelateId()).getNickname());
                    }
                }
                if (TicketTypeEnum.TENANT.getType().equals(item.getType())) {
                    item.setTenantNickname(shopMap.get(item.getRelateId()).getShopName());
                }
                if (TicketTypeEnum.USER_LEVEL.getType().equals(item.getType())) {
                    VipReq vipReq = JSON.parseObject(item.getFeature(), VipReq.class);
                    User user = userMapper.findOneByUsername(vipReq.getPhone());
                    item.setUserAvatar(user.getAvatar());
                    item.setUserNickname(user.getNickname());
                }
            });
        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<TicketVO> getTicketDetail(Long id) {
        User currentUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (!"13157141999".equals(currentUser.getUsername())) {
            return null;
        }
        TicketVO vo = new TicketVO();
        Ticket ticket = ticketMapper.selectByPrimaryKey(id);
        List<Long> adminIds = new ArrayList<>();
        adminIds.add(ticket.getAdminId());
        adminIds.add(ticket.getFirstAdminId());
        adminIds.add(ticket.getSecondAdminId());
        Map<Long, Admin> adminMap = daoService.getAdminMap(adminIds);
        if (ticket.getAdminId().equals(HIPO_ADMIN_ID) || ticket.getFirstAdminId().equals(HIPO_ADMIN_ID) || ticket.getSecondAdminId().equals(HIPO_ADMIN_ID)) {
            BeanUtils.copyProperties(ticket, vo);
            vo.setAvatar(adminMap.get(vo.getAdminId()).getAvatar());
            vo.setNickname(adminMap.get(vo.getAdminId()).getNickname());
            vo.setRealName(adminMap.get(vo.getAdminId()).getRealName());
            vo.setFirstAvatar(adminMap.get(vo.getFirstAdminId()).getAvatar());
            vo.setFirstNickname(adminMap.get(vo.getFirstAdminId()).getNickname());
            if (TicketLevelEnum.SECOND_AUDIT.getLevel().equals(vo.getLevel())) {
                vo.setSecondAvatar(adminMap.get(vo.getSecondAdminId()).getAvatar());
                vo.setSecondNickname(adminMap.get(vo.getSecondAdminId()).getNickname());
            }
            if (TicketTypeEnum.EXCHANGE_BALANCE.getType().equals(vo.getType()) || TicketTypeEnum.COMMISSION.getType().equals(vo.getType())) {
                User user = userMapper.selectByPrimaryKey(vo.getRelateId());
                vo.setUserAvatar(user.getAvatar());
                vo.setUserNickname(user.getNickname());
            }
            if (TicketTypeEnum.TENANT.getType().equals(vo.getType())) {
                Shop shop = shopMapper.selectByPrimaryKey(vo.getRelateId());
                vo.setTenantNickname(shop.getShopName());
            }
            return new ResultData<>(vo);
        }
        return new ResultData<>(null);
    }


    @Override
    public BaseResp firstAuditTicket(Ticket req) {
        User currentUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (!"13157141999".equals(currentUser.getUsername())) {
            return null;
        }
        Ticket ticket = ticketMapper.selectByPrimaryKey(req.getId());
        if (!ticket.getFirstAdminId().equals(HIPO_ADMIN_ID)) {
            return new BaseResp(ResultCode.NOT_AUDIT_ADMIN);
        } else {
            if (!TicketAuditStatusEnum.WAIT_AUDIT.getAduitStatus().equals(ticket.getAuditStatus())) {
                return new BaseResp(ResultCode.AUDIT_FAIL);
            }
            if (TicketAuditStatusEnum.FIRST_PASS.getAduitStatus().equals(req.getAuditStatus()) || TicketAuditStatusEnum.FIRST_REJECT.getAduitStatus().equals(req.getAuditStatus())) {
                ticket.setAuditStatus(req.getAuditStatus());
                ticket.setFirstRemark(req.getFirstRemark());
                ticket.setFirstAuditTime(new Date());
                ticket.setUpdatedAt(new Date());
                ticketMapper.updateByPrimaryKey(ticket);

                if (TicketAuditStatusEnum.FIRST_PASS.getAduitStatus().equals(req.getAuditStatus())) {
                    isCompleteTicket(ticket);
                }
            }
        }
        return new BaseResp();
    }

    @Override
    public BaseResp secondAuditTicket(Ticket req) {
        User currentUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (!"13157141999".equals(currentUser.getUsername())) {
            return null;
        }
        Ticket ticket = ticketMapper.selectByPrimaryKey(req.getId());
        if (!ticket.getFirstAdminId().equals(HIPO_ADMIN_ID)) {
            return new BaseResp(ResultCode.NOT_AUDIT_ADMIN);
        } else {
            if (TicketAuditStatusEnum.WAIT_AUDIT.getAduitStatus().equals(ticket.getAuditStatus()) || TicketAuditStatusEnum.FIRST_REJECT.getAduitStatus().equals(ticket.getAuditStatus())) {
                return new BaseResp(ResultCode.FIRST_AUDIT_NOT_PASS);
            }
            if (!TicketAuditStatusEnum.FIRST_PASS.getAduitStatus().equals(ticket.getAuditStatus())) {
                return new BaseResp(ResultCode.AUDIT_FAIL);
            }
            if (!TicketLevelEnum.SECOND_AUDIT.getLevel().equals(ticket.getLevel())) {
                return new BaseResp(ResultCode.NOT_NEED_SECOND_AUDIT);
            }
            if (TicketAuditStatusEnum.SECOND_PASS.getAduitStatus().equals(req.getAuditStatus()) || TicketAuditStatusEnum.SECOND_REJECT.getAduitStatus().equals(req.getAuditStatus())) {
                ticket.setAuditStatus(req.getAuditStatus());
                ticket.setSecondRemark(req.getSecondRemark());
                ticket.setSecondAuditTime(new Date());
                ticket.setUpdatedAt(new Date());
                ticketMapper.updateByPrimaryKey(ticket);

                if (TicketAuditStatusEnum.SECOND_PASS.getAduitStatus().equals(req.getAuditStatus())) {
                    isCompleteTicket(ticket);
                }
            }
        }
        return new BaseResp();
    }

    private void isCompleteTicket(Ticket ticket) {
        if ((TicketAuditStatusEnum.FIRST_PASS.getAduitStatus().equals(ticket.getAuditStatus()) && TicketLevelEnum.FIRST_AUDIT.getLevel().equals(ticket.getLevel())) || (TicketAuditStatusEnum.SECOND_PASS.getAduitStatus().equals(ticket.getAuditStatus()) && TicketLevelEnum.SECOND_AUDIT.getLevel().equals(ticket.getLevel()))) {
            //通过赠送身份审核
            if (TicketTypeEnum.USER_LEVEL.getType().equals(ticket.getType())) {
                createUserLevel(JSON.parseObject(ticket.getFeature(), VipReq.class));
            }
        }
    }

    //todo
    public BaseResp createUserLevel(VipReq req) {
        User user = userMapper.findOneByUsername(req.getPhone());

        if (user == null) {
            return new BaseResp(ResultCode.ACCT_NOT_EXIST);
        }
        if (UserStatusEnum.BAN.getStatus().equals(user.getStatus())) {
            return new BaseResp(ResultCode.USER_BAN);
        }
        switch (UserLevelEnum.getByLevel(req.getLevel())) {
            case CUSTOMER:
                levelService.addOneRecommend(user, req.getIsBuyer());
                break;
            case MEMBER_L1:
                levelService.addOneMember(user, req.getIsBuyer(), req.getMemberState());
                break;
            case PARTNER_L1:
                // 允许重复设置合伙人
                levelService.addOnePartner(user, req.getIsBuyer());
                break;
            case SHAREHOLDER_L1:
                if (user.getLevel() >= UserLevelEnum.SHAREHOLDER_L1.getLevel()) {
                    return new BaseResp(ResultCode.IS_OVER_SHAREHOLDER);
                }
                levelService.addOneShareholder(user, req.getIsBuyer());
                break;
            case SHAREHOLDER_L2:
                // 如果小于董事身份，则先给他一个董事身份
                if (user.getLevel() < UserLevelEnum.SHAREHOLDER_L1.getLevel()) {
                    levelService.addOneShareholder(user, req.getIsBuyer());
                }

                // 然后直接晋升为副总裁
                identityMapper.updateLevelAndShareholderLevelByUserId(UserLevelEnum.SHAREHOLDER_L2.getLevel(), UserLevelEnum.SHAREHOLDER_L2.getLevel(), user.getId());
                updateUserLevel(user.getId(), UserLevelEnum.SHAREHOLDER_L2.getLevel());

                break;
            case SHAREHOLDER_L3:
                // 如果小于董事身份，则先给他一个董事身份
                if (user.getLevel() < UserLevelEnum.SHAREHOLDER_L1.getLevel()) {
                    levelService.addOneShareholder(user, req.getIsBuyer());
                }

                // 然后直接晋升为总裁
                identityMapper.updateLevelAndShareholderLevelByUserId(UserLevelEnum.SHAREHOLDER_L3.getLevel(), UserLevelEnum.SHAREHOLDER_L3.getLevel(), user.getId());
                updateUserLevel(user.getId(), UserLevelEnum.SHAREHOLDER_L3.getLevel());
                break;
            case PARTNER_DIRECTOR:
                levelService.addOneMember(user, req.getIsBuyer(), MemberStateEnum.SUPER.getType());
                levelService.addOnePartner(user, req.getIsBuyer());
                levelService.addOneShareholder(user, req.getIsBuyer());
                Identity identity = identityMapper.findOneByUserId(user.getId());
                identity.setDirector(DirectorEnum.DIRECTOR.getType());
                identity.setPartnerAccount(identity.getPartnerAccount() + Integer.valueOf(daoService.getHipoConfigValue(HipoConfigEnum.DIRECTOR_PARTNER_ACCOUNT_COUNT.getConfig())));
                identity.setAreaAccount(identity.getAreaAccount());
                identityMapper.updateByPrimaryKeySelective(identity);
                break;
            case COMPANY:
                Identity identity2 = identityMapper.findOneByUserId(user.getId());
                identity2.setShareholderState(ShareholderStateEnum.COMPANY.getType());
                identityMapper.updateByPrimaryKeySelective(identity2);
                break;
            default:
                break;
        }

        // 保存用户的身份信息到userInfo
        UserInfo userInfo = UserInfo.builder().idCard(req.getIdCard()).realName(req.getName()).userId(user.getId()).updatedAt(new Date()).build();
        userInfoMapper.updateIdCardAndRealNameAndUpdatedAtByUserId(userInfo);

        // 如果是购买类型的，则发放分红和奖励等
        if (IsBuyerEnum.BUYER.getType().equals(req.getIsBuyer())) {
            commissionService.prepareIdentityCommission(user, IdentityTypeEnum.getIdentityTypeByLevel(req.getLevel()));
        }

        return new BaseResp();
    }

    public void updateUserLevel(Long userId, Integer level) {
        Byte type = IdentityTypeEnum.getTypeByLevel(level);

        userMapper.updateLevelById(level, userId);

        // 更新自己作为下级的所有等级
        userGroupMapper.updateMemberLevelByMemberIdAndMemberType(level, userId, type);

        // 更新自己作为上级的所有等级
        userGroupMapper.updateCaptainLevelByCaptainIdAndCaptainType(level, userId, type);

        // 同步更新上下级表中的下级用户等级
        userRelationshipMapper.updateSubordinateLevelBySubordinateId(level, userId);

        // 如果是此人升级为运营中心了，则他团队的所有成员的上级运营中心，将都改为他
        if (UserLevelEnum.SHAREHOLDER_L1.getLevel().equals(level)) {
            userGroupMapper.updateShareholderIdByCaptainId(userId, userId);
        }
    }

    @Override
    public BaseResp applyCelebrity(User user) throws ResultCodeException {
        // 是否已成为达人
        if (user.getLevel().equals(UserLevelEnum.PARTNER_L1.getLevel())) {
            throw new ResultCodeException(ResultCode.IS_INSUFFICIENT);
        }
        // 查看粉丝量
        UserInfo userInfo = userInfoMapper.findOneByUserId(user.getId());
        if (userInfo == null) {
            return new BaseResp();
        }
        String value = daoService.getHipoConfigValue(HipoConfigEnum.FANS_COUNT.getConfig());
        if (userInfo.getFansCount() < Long.parseLong(value)) {
            throw new ResultCodeException(ResultCode.COUNT_INSUFFICIENT);
        }
        UserCelebrity celebrity = userCelebrityMapper.getByUserId(user.getId());
        if (celebrity != null) {
            celebrity.setStatus(UserCelebrityStatus.WAIT_AUDIT.getCode());
            celebrity.setRemark("");
            userCelebrityMapper.insert(celebrity);
        } else {
            // 添加审核记录
            UserCelebrity userCelebrity = new UserCelebrity();
            userCelebrity.setUserId(user.getId());
            userCelebrity.setStatus(UserCelebrityStatus.WAIT_AUDIT.getCode());
            userCelebrity.setCreated(new Date());
            userCelebrityMapper.insert(userCelebrity);
        }
        return new BaseResp();
    }
}